博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树
阅读量:4699 次
发布时间:2019-06-09

本文共 3877 字,大约阅读时间需要 12 分钟。

考虑没有询问,直接给你一个图问联通块怎么做。

并查集是吧。

现在想要动态地做,那么应该要用LCT。

考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通。

如果联通了,应该会形成一个环,我们其实可以把环中最早加进来的边删掉再加进来这条边,也不影响整个的联通性对不对。

于是我们用LCT维护一下最大生成树,顺便求出一个\(pre[i]\)表示\(i\)这条边加进来以后,环里面最早加进来的边的编号。

可以发现\(pre[i]\leq l\)那就说明,\(i\)这条边是连接了联通块的。\(l..r\)的区间内,有一个这样的边,就会少一个联通块。

这个用主席树维护就好了。

#include
#include
#include
#include
#define lc t[o].c[0]#define rc t[o].c[1]#define REP(i,a,n) for(register int i(a);i<=(n);++i)#define dbg(...) fprintf(stderr,__VA_ARGS__)const int SZ=(1<<21)+1;char ibuf[SZ],*iS,*iT,obuf[SZ+128],*oS=obuf,*oT=obuf+SZ-1;#ifdef ONLINE_JUDGE#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SZ,stdin),(iS==iT?EOF:*iS++)):*iS++)#else#define gc() getchar()#endiftemplate
inline void read(I&x){char c=gc();int f=1;for(;c<'0'||c>'9';c=gc())c=='-'?f=-1:0;for(x=0;c>='0'&&c<='9';c=gc())x=(x<<1)+(x<<3)+(c&15);f==-1?x=-x:0;}inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}#define printf(...) oS>oT&&(flush(),1),oS+=sprintf(oS,__VA_ARGS__)template
inline char SMAX(A&a,const B&b){return a
inline char SMIN(A&a,const B&b){return a>b?a=b,1:0;}const int N=200000+7,INF=0x3f3f3f3f;int n,m,x,y,Q,tp,la;struct Edges{int x,y;}e[N];struct LCT{ struct Node{int min,c[2],fa,rev;inline Node():min(INF){}}t[N<<1];int S[N<<1],top,nod;inline Node&operator[](const int&x){return t[x];} inline char Isroot(int o){return t[t[o].fa].c[0]!=o&&t[t[o].fa].c[1]!=o;} inline char Identify(int o){return t[t[o].fa].c[0]!=o;} inline void Connect(int fa,int o,char d){t[fa].c[d]=o;t[o].fa=fa;} inline void Pushup(int o){t[o].min=o>n?o:INF;lc&&SMIN(t[o].min,t[lc].min);rc&&SMIN(t[o].min,t[rc].min);} inline void Rotate(int o){int fa=t[o].fa,pa=t[fa].fa,d1=Identify(o),d2=Identify(fa),b=t[o].c[d1^1];!Isroot(fa)&&(t[pa].c[d2]=o);t[o].fa=pa;Connect(fa,b,d1);Connect(o,fa,d1^1);Pushup(fa),Pushup(o);} inline void Pushdown(int o){t[o].rev&&(t[o].rev=0,lc&&(t[lc].rev^=1,std::swap(t[lc].c[0],t[lc].c[1]),1),rc&&(t[rc].rev^=1,std::swap(t[rc].c[0],t[rc].c[1]),1));} inline void Splay(int o){ int x=o;S[top=1]=x;while(!Isroot(x))S[++top]=x=t[x].fa;while(top)Pushdown(S[top--]); while(!Isroot(o)){int fa=t[o].fa;if(Isroot(fa))Rotate(o);else if(Identify(o)==Identify(fa))Rotate(fa),Rotate(o);else Rotate(o),Rotate(o);} } inline void Access(int o){for(register int x=0;o;o=t[x=o].fa)Splay(o),rc=x,Pushup(o);} inline void Makeroot(int o){Access(o);Splay(o);t[o].rev^=1;std::swap(lc,rc);} inline int Findroot(int o){Access(o);Splay(o);while(lc)Pushdown(o),o=lc;Splay(o);return o;} inline void Split(int x,int y){Makeroot(x);Access(y);Splay(y);} inline void Link(int x,int y){Makeroot(x);if(Findroot(y)^x)t[x].fa=y;} inline void Cut(int x,int y){Split(x,y);if(t[y].c[0]&&!t[x].c[1])t[y].c[0]=t[x].fa=0;Pushup(y);}//错误笔记: 清错了,把t[x].c[0]清零了}lct;#undef lc#undef rcstruct President_Tree{ struct Node{int lc,rc,val;}t[N*21];int rt[N],nod; inline void Insert(int &o,int p,int L,int R,int x,int k){t[o=++nod]=t[p];t[o].val+=k;if(L==R)return;int M=(L+R)>>1;x<=M?Insert(t[o].lc,t[p].lc,L,M,x,k):Insert(t[o].rc,t[p].rc,M+1,R,x,k);} inline int Query(int o,int p,int L,int R,int x){if(L==R)return t[o].val-t[p].val;int M=(L+R)>>1;return x>M?t[t[o].lc].val-t[t[p].lc].val+Query(t[o].rc,t[p].rc,M+1,R,x):Query(t[o].lc,t[p].lc,L,M,x);}}pt;int main(){ read(n),read(m),read(Q),read(tp); REP(i,1,m){ read(x),read(y);int pre=x==y?m:0,p;e[i]=Edges{x,y};//错误笔记:自环需要特判掉 if(x!=y&&lct.Findroot(x)==lct.Findroot(y))lct.Split(x,y),p=lct[y].min,pre=p-n,lct.Cut(p,e[p-n].x),lct.Cut(p,e[p-n].y); if(x!=y)lct[i+n].min=i+n,lct.Link(x,i+n),lct.Link(y,i+n); pt.Insert(pt.rt[i],pt.rt[i-1],0,m,pre,1);//错误笔记:注意边权和点权之间要用+-n来切换 } REP(i,1,Q){ read(x),read(y);if(tp)x^=la,y^=la; printf("%d\n",la=n-pt.Query(pt.rt[y],pt.rt[x-1],0,m,x-1));//错误笔记:漏强制在线 }return flush(),0;}

转载于:https://www.cnblogs.com/hankeke/p/BZOJ3514.html

你可能感兴趣的文章
软件工程设计之四则运算
查看>>
SpringMVC @ResponseBody 406
查看>>
HDOJ---2824 The Euler function[欧拉函数]
查看>>
KMP算法
查看>>
Atlas学习之开始篇[转]
查看>>
第二章 在HTML页面里使用javaScript
查看>>
【Educational Codeforces Round 48 (Rated for Div. 2) D】Vasya And The Matrix
查看>>
正则表达式的性能评测
查看>>
CF1172B Nauuo and Circle
查看>>
CF1178D Prime Graph
查看>>
CF1190D Tokitsukaze and Strange Rectangle
查看>>
CF1202F You Are Given Some Letters...
查看>>
CF1179C Serge and Dining Room
查看>>
CF1168B Good Triple
查看>>
CF1208E Let Them Slide
查看>>
AT2000 Leftmost Ball
查看>>
CF1086E Beautiful Matrix
查看>>
在单位上班的25条建议(建议收藏)
查看>>
web前端--http协议
查看>>
欧拉定理证明&阶乘的逆元
查看>>