BZOJ3514: Codechef MARCH14 GERALD07加强版
2017-02-22 16:22
141 查看
传送门
闲来无事练两个板子。
一个思路上的trick就是判定边对是否更新连通块数量的贡献,如果一条边将一个子图连成环,那么这个是对连通块数量的减少没有贡献的。
考虑用LCT维护联通与环即可,我们预处理出每条边对应的最早的能连成环的边,对于一个区间$[L,R]$,如果最早能形成环的边在这个区间之前,那么就可以认为这个边是对答案有贡献的,主席树维护即可。
另外需要注意自环的情况。
闲来无事练两个板子。
一个思路上的trick就是判定边对是否更新连通块数量的贡献,如果一条边将一个子图连成环,那么这个是对连通块数量的减少没有贡献的。
考虑用LCT维护联通与环即可,我们预处理出每条边对应的最早的能连成环的边,对于一个区间$[L,R]$,如果最早能形成环的边在这个区间之前,那么就可以认为这个边是对答案有贡献的,主席树维护即可。
另外需要注意自环的情况。
//BZOJ 3514 //by Cydiater //2017.2.22 #include <iostream> #include <queue> #include <map> #include <cstring> #include <string> #include <ctime> #include <cmath> #include <iomanip> #include <cstdlib> #include <cstdio> #include <algorithm> #include <bitset> #include <set> #include <complex> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) #define cmax(a,b) a=max(a,b) #define cmin(a,b) a=min(a,b) #define pii pair<int,int> #define fi first #define se second #define mp make_pair const int MAXN=5e5+5; const int oo=0x3f3f3f3f; inline int read(){ char ch=getchar();int x=0,f=1; while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int N,M,K,type,fri[MAXN]; pii E[MAXN]; namespace LCT{ struct tr{ int son[2],fa,tag,id,val; tr(){val=oo;} void clear(){son[0]=son[1]=fa=tag=id=0;val=oo;} }t[MAXN]; inline int isrt(int k){return t[t[k].fa].son[0]!=k&&t[t[k].fa].son[1]!=k;} inline int get(int k){return t[t[k].fa].son[1]==k;} inline void rev(int k){ if(!k)return; swap(t[k].son[0],t[k].son[1]); t[k].tag^=1; } inline void reload(int k){ if(!k)return; t[k].id=k; int s1=t[k].son[0],s2=t[k].son[1]; int i1=t[s1].id,i2=t[s2].id; if(t[i1].val<t[t[k].id].val)t[k].id=i1; if(t[i2].val<t[t[k].id].val)t[k].id=i2; } inline void Pushdown(int k){ if(!k)return; if(t[k].tag){ rev(t[k].son[0]);rev(t[k].son[1]); t[k].tag^=1; } } inline void rotate(int k){ int old=t[k].fa,oldf=t[old].fa,which=get(k); if(!isrt(old))t[oldf].son[old==t[oldf].son[1]]=k; t[old].son[which]=t[k].son[which^1];t[t[old].son[which]].fa=old; t[k].son[which^1]=old;t[old].fa=k;t[k].fa=oldf;t[0].clear(); reload(old);reload(k); } int stack[MAXN],top=0; inline void splay(int k){ top=0;stack[++top]=k; for(int tmp=k;!isrt(tmp);tmp=t[tmp].fa)stack[++top]=t[tmp].fa; while(top)Pushdown(stack[top--]); while(!isrt(k)){ int old=t[k].fa; if(!isrt(old))rotate(get(old)==get(k)?old:k); rotate(k); } } void access(int k){ int tmp=0; while(k){ splay(k);t[k].son[1]=tmp; reload(k);tmp=k;k=t[k].fa; } } void mrt(int k){ access(k);splay(k);rev(k); } int grt(int k){ access(k);splay(k); while(t[k].son[0])k=t[k].son[0]; return k; } void Link(int x,int y){ mrt(x);t[x].fa=y; } void Cut(int x,int y){ mrt(x);access(y);splay(y);t[y].son[0]=t[x].fa=0; reload(y); } int res(int x,int y){ mrt(x);access(y);splay(y); return t[y].id; } void Go(){ up(i,1,M){ int x=E[i].fi,y=E[i].se; if(x==y)continue; if(grt(x)==grt(y)){ int id=res(x,y)-N; fri[i]=id; int tx=E[id].fi,ty=E[id].se; Cut(tx,id+N);Cut(ty,id+N); } int id=i+N; t[id].val=i;t[id].id=id; Link(x,id);Link(y,id); } } } namespace ChairManTree{ int cnt=0,root[MAXN]; struct tree{ int son[2],siz; }t[MAXN<<3]; int NewNode(int s1,int s2,int siz){ t[++cnt].son[0]=s1;t[cnt].son[1]=s2; t[cnt].siz=siz; return cnt; } void Build(int L,int R,int &k,int lr,int val){ k=NewNode(t[lr].son[0],t[lr].son[1],t[lr].siz+1); if(L==R)return; int mid=(L+R)>>1; if(val<=mid) Build(L,mid,t[k].son[0],t[lr].son[0],val); else Build(mid+1,R,t[k].son[1],t[lr].son[1],val); } int Query(int L,int R,int r1,int r2,int LIM){ int lsiz=t[t[r2].son[0]].siz-t[t[r1].son[0]].siz; int siz=t[r2].siz-t[r1].siz,mid=(L+R)>>1; if(L==R) return siz; if(mid>LIM) return Query(L,mid,t[r1].son[0],t[r2].son[0],LIM); else if(R<=LIM) return siz; else if(mid==LIM) return lsiz; else if(mid+1<=LIM) return lsiz+Query(mid+1,R,t[r1].son[1],t[r2].son[1],LIM); } } int last=0,L,R; namespace solution{ void Prepare(){ N=read();M=read();K=read();type=read(); up(i,1,M){ int x=read(),y=read(); E[i]=mp(x,y);if(x==y)fri[i]=M+1; } LCT::Go(); } void Solve(){ //up(i,1,M)printf("%d ",fri[i]);puts(""); using namespace ChairManTree; up(i,1,M)Build(0,M+1,root[i],root[i-1],fri[i]); while(K--){ L=read();R=read(); if(type){L^=last;R^=last;} if(L>R)swap(L,R); printf("%d\n",last=max(N-Query(0,M+1,root[L-1],root[R],L-1),1)); } } } int main(){ //freopen("input.in","r",stdin); using namespace solution; Prepare(); Solve(); return 0; }
相关文章推荐
- BZOJ3514: Codechef MARCH14 GERALD07加强版
- *BZOJ3514: Codechef MARCH14 GERALD07加强版
- bzoj3514 Codechef MARCH14 GERALD07加强版
- BZOJ3514: Codechef MARCH14 GERALD07加强版
- BZOJ3514:Codechef MARCH14 GERALD07加强版 (LCT+可持久化线段树)
- Bzoj3514:Codechef MARCH14 GERALD07加强版:LCT+主席树
- [bzoj3514][动态树]Codechef MARCH14 GERALD07加强版
- BZOJ 3514 Codechef MARCH14 GERALD07加强版
- BZOJ 3514 Codechef MARCH14 GERALD07加强版 LCT+主席树
- 【bzoj3514】Codechef MARCH14 GERALD07加强版 link cut tree+主席树
- [BZOJ]3514: Codechef MARCH14 GERALD07加强版
- 【 bzoj 3514 】Codechef MARCH14 GERALD07加强版 - LCT
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版,LCT+主席树
- [bzoj3514]Codechef MARCH14 GERALD07加强版
- 2017.10.17 Codechef MARCH14 GERALD07加强版 失败总结
- bzoj3514: Codechef MARCH14 GERALD07加强版
- bzoj 3514: Codechef MARCH14 GERALD07加强版 lct+可持久化线段树
- Bzoj3514: Codechef MARCH14 GERALD07加强版
- BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT
- BZOJ 3514 Codechef MARCH14 GERALD07加强版 Link-Cut-Tree+划分树