【BZOJ3514】Codechef MARCH14 GERALD07加强版(LCT)
题意:N个点M条边的无向图,q次询问保留图中编号在[l,r]的边的时候图中的联通块个数。
询问加密,强制在线
n,m,q<=200000
题意:RYZ作业
以下转载自hzwer http://hzwer.com/4358.html 本人实力有限难以清晰描述
有一个比较猎奇的做法:首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去
并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr[i] = 0;
这个显然是可以用LCT来弄的对吧。
然后对于每个询问,我们的答案就是对l~r中ntr小于l的边求和,并用n减去这个值
正确性可以YY一下:
如果一条边的ntr >= l,那么显然他可以与从l ~ r中的边形成环,那么它对答案没有贡献
反之如果一条边的ntr < l那么它与从l ~ r中的边是不能形成环的,那么他对答案的贡献为-1
对于查询从l ~ r中有多少边的ntr小于l,我反正是用的函数式线段树
话说LCT自带十倍常数 被卡了一天半 最后还是把swap和isroot拆出来才卡过的……
- var t,c:array[..,..]of longint;
- mx,a,b,rev,fa,root,q:array[..]of longint;
- x,y:array[..]of longint;
- n,m,cnt,i,k,tp,tmp,lastans,l,r,top,tt:longint;
- {function isroot(x:longint):boolean;
- begin
- if (t[fa[x],0]<>x)and(t[fa[x],1]<>x) then exit(true);
- exit(false);
- end;
- }
- {procedure swap(var x,y:longint);
- var t:longint;
- begin
- t:=x; x:=y; y:=t;
- end; }
- procedure pushup(x:longint);
- var l,r:longint;
- begin
- l:=t[x,]; r:=t[x,];
- mx[x]:=x;
- if b[mx[l]]<b[mx[x]] then mx[x]:=mx[l];
- if b[mx[r]]<b[mx[x]] then mx[x]:=mx[r];
- end;
- procedure pushdown(x:longint);
- var l,r:longint;
- begin
- l:=t[x,]; r:=t[x,];
- if rev[x]> then
- begin
- rev[x]:=rev[x] xor ; rev[l]:=rev[l] xor ; rev[r]:=rev[r] xor ;
- // swap(t[x,],t[x,]);
- tt:=t[x,]; t[x,]:=t[x,]; t[x,]:=tt;
- end;
- end;
- procedure rotate(x:longint);
- var y,z,l,r:longint;
- begin
- y:=fa[x]; z:=fa[y];
- if t[y,]=x then l:=
- else l:=;
- r:=l xor ;
- // if not isroot(y) then
- if (t[fa[y],]=y)or(t[fa[y],]=y) then
- begin
- if t[z,]=y then t[z,]:=x
- else t[z,]:=x;
- end;
- fa[y]:=x; fa[x]:=z; fa[t[x,r]]:=y;
- t[y,l]:=t[x,r]; t[x,r]:=y;
- pushup(y);
- pushup(x);
- end;
- procedure splay(x:longint);
- var y,z,k:longint;
- begin
- inc(top); q[top]:=x;
- k:=x;
- // while not isroot(k) do
- while (t[fa[k],]=k)or(t[fa[k],]=k) do
- begin
- inc(top); q[top]:=fa[k];
- k:=fa[k];
- end;
- while top> do
- begin
- pushdown(q[top]);
- dec(top);
- end;
- // while not isroot(x) do
- while (t[fa[x],]=x)or(t[fa[x],]=x) do
- begin
- y:=fa[x]; z:=fa[y];
- //if not isroot(y) then
- if (t[fa[y],]=y)or(t[fa[y],]=y) then
- begin
- if (t[y,]=x)xor(t[z,]=y) then rotate(x)
- else rotate(y);
- end;
- rotate(x);
- end;
- end;
- procedure access(x:longint);
- var last:longint;
- begin
- last:=;
- while x> do
- begin
- splay(x); t[x,]:=last; pushup(x);
- last:=x; x:=fa[x];
- end;
- end;
- function findroot(x:longint):longint;
- var k:longint;
- begin
- access(x); splay(x);
- k:=x;
- while t[k,]<> do k:=t[k,];
- exit(k);
- end;
- procedure makeroot(x:longint);
- begin
- access(x); splay(x); rev[x]:=rev[x] xor ;
- end;
- procedure link(x,y:longint);
- begin
- makeroot(x); fa[x]:=y;
- end;
- procedure cut(x,y:longint);
- begin
- makeroot(x); access(y); splay(y); t[y,]:=; fa[x]:=;
- end;
- procedure update(l,r:longint;var p:longint;x:longint);
- var mid:longint;
- begin
- inc(cnt); c[cnt]:=c[p];
- p:=cnt; inc(c[p,]);
- if l=r then exit;
- mid:=(l+r)>>;
- if x<=mid then update(l,mid,c[p,],x)
- else update(mid+,r,c[p,],x);
- end;
- function query(p1,p2,l,r,x:longint):longint;
- var mid:longint;
- begin
- if r=x then exit(c[p2,]-c[p1,]);
- mid:=(l+r)>>;
- if x<=mid then exit(query(c[p1,],c[p2,],l,mid,x))
- else exit(c[c[p2,],]-c[c[p1,],]+query(c[p1,],c[p2,],mid+,r,x));
- end;
- begin
- assign(input,'data.in'); reset(input);
- assign(output,'bzoj3514.out'); rewrite(output);
- readln(n,m,k,tp);
- fillchar(b,sizeof(b),$1f);
- for i:= to m do
- begin
- readln(x[i],y[i]);
- if x[i]=y[i] then a[i]:=i
- else
- begin
- if findroot(x[i])=findroot(y[i]) then
- begin
- makeroot(x[i]); access(y[i]); splay(y[i]);
- tmp:=mx[y[i]];
- a[i]:=tmp-n;
- cut(x[tmp-n],tmp); cut(tmp,y[tmp-n]);
- b[n+i]:=i; mx[n+i]:=n+i;
- link(x[i],i+n); link(i+n,y[i]);
- end
- else
- begin
- b[n+i]:=i; mx[n+i]:=n+i;
- link(x[i],i+n); link(i+n,y[i]);
- end;
- end;
- end;
- //for i:= to m do writeln(a[i]);
- for i:= to m do
- begin
- root[i]:=root[i-];
- update(,m,root[i],a[i]);
- end;
- for i:= to k do
- begin
- readln(l,r);
- if tp= then
- begin
- l:=l xor lastans;
- r:=r xor lastans;
- end;
- lastans:=n-query(root[l-],root[r],,m,l-);
- writeln(lastans);
- end;
- close(input);
- close(output);
- end.
【BZOJ3514】Codechef MARCH14 GERALD07加强版(LCT)的更多相关文章
- [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2177 Solved: 834 ...
- bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树
Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1951 Solved: 746[Submi ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3514 题意概括 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. N ...
- BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树
自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树
题面 考虑没有询问,直接给你一个图问联通块怎么做. 并查集是吧. 现在想要动态地做,那么应该要用LCT. 考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通. 如果联通 ...
- 【LCT+主席树】BZOJ3514 Codechef MARCH14 GERALD07加强版
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2023 Solved: 778 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )
从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1312 Solved: 501 ...
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树
题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...
随机推荐
- 自己太水了—HDOJ_2212
Problem Description A DFS(digital factorial sum) number is found by summing the factorial of every d ...
- 复合词UVa10391(STL简单应用)
一.题目 输入一系列由小写字母组成的单词.输入已按照字典序排序(这句话就是个陷阱),且不超过120000个.找出所有的复合词,即恰好由两个单词连接而成的单词. 二.解题思路 要么枚举两两拼接的情况,O ...
- currentStyle和getComputedStyle来获取外部样式
currentStyle和getComputedStyle来获取外部样式 通过document.getElementById(id).style.XXX就可以获取到XXX的值,但意外的是,这样做只能取 ...
- java程序-类的高级特性
创建Employee类,在类中定义三个属性:编号,姓名,年龄,然后在构造方法里初始化这三个属性,最后在实现接口中的定义的CompareTo方法,将对象按编号升序排列. 代码如下:(程序可能有些错误,方 ...
- 实现类似AOP的封装和配置
这是张孝祥老师Java进阶讲解中最后一个视频,就是实现类似spring中的AOP的封装和配置,特别特别小型的一个框架雏形,但是spring中的核心思想还是体现出来了,真的厉害,张老师!!! 一.重点知 ...
- shell脚本,计算1+2+3+....100等于多少?
第一种方法,通过for循环来计算[root@localhost wyb]# cat yibai.sh #!/bin/bash #从1+++...100的结果 i= ` do sum=$(($sum+i ...
- 解析IPV4报文 和IPV6 报文的 checksum
解析IPV4报文和IPV6报文的checksum的算法: 校验和(checksum)算法,简单的说就是16位累加的反码运算: 计算函数如下: 我们在计算时是主机字节序,计算的结果封装成IP包时是网络字 ...
- Promise中的next 另一个用法
const chainAsync = fns => { let curr = 0 ; const next = (...args) => fns[curr++](next,...args) ...
- linux配置MySql表名不区分大小写
1.Linux下mysql安装完后是默认:区分表名的大小写,不区分列名的大小写:2.用root帐号登录后,在/etc/my.cnf中的[mysqld]后添加添加lower_case_table_nam ...
- 简单的Redis数据迁移
dump迁移 1.安装redis-dump工具 sudo apt-get install ruby rubygems ruby-devel -y gem sources --add http://ge ...