BZOJ4025(LCT+LCT+LinkCutTree)
2017-08-15 20:17
465 查看
题面
最近学CDQ分治,别人给了我这题,但我分治好菜,只会果题,既然是有加边删边的图论题,就考虑LCT吧,所以就有了这个标题。
题意是给你N个点,有加边和删边,输出每次操作后它是不是一个二分图。
常识告诉我们,二分图的充要条件是不存在奇环,而LCT的难点就是在出现环的时候的处理。
假如加入了一条边,出现了奇环,那么是到这条边被删前,这个图都不是二分图吗?
显然不是,是到这个环有一条边被删之前,这个图都不是二分图,故要维护路径上最早删除的边,并把它从图树上Cut掉,把这条边Link上去,然后作上标记,表示这条边被删前都不是二分图。
如果来了一条边,构成了一个偶环,因为偶数+偶数还是偶数,偶数+奇数=奇数,所以不影响答案,还是把环上最早被删的边在树上Cut掉,把这条边Link上去。
如果不构成环就Link上去。
删除边时,如果这条边还在树上,Cut掉就可以了。
这个代码长长长,还自带大常数
最近学CDQ分治,别人给了我这题,但我分治好菜,只会果题,既然是有加边删边的图论题,就考虑LCT吧,所以就有了这个标题。
题意是给你N个点,有加边和删边,输出每次操作后它是不是一个二分图。
常识告诉我们,二分图的充要条件是不存在奇环,而LCT的难点就是在出现环的时候的处理。
假如加入了一条边,出现了奇环,那么是到这条边被删前,这个图都不是二分图吗?
显然不是,是到这个环有一条边被删之前,这个图都不是二分图,故要维护路径上最早删除的边,并把它从图树上Cut掉,把这条边Link上去,然后作上标记,表示这条边被删前都不是二分图。
如果来了一条边,构成了一个偶环,因为偶数+偶数还是偶数,偶数+奇数=奇数,所以不影响答案,还是把环上最早被删的边在树上Cut掉,把这条边Link上去。
如果不构成环就Link上去。
删除边时,如果这条边还在树上,Cut掉就可以了。
这个代码长长长,还自带大常数
#include <iostream> #include <fstream> #include <algorithm> #include <cmath> #include <ctime> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; #define mmst(a, b) memset(a, b, sizeof(a)) #define mmcp(a, b) memcpy(a, b, sizeof(b)) typedef long long LL; const int N=300300,oo=1e9; int cnt,n,m,t,cur; int x ,y ,op ,ed ; int ans ; bool in ; void read(int &hy) { hy=0; char cc=getchar(); while(cc<'0'||cc>'9') cc=getchar(); while(cc>='0'&&cc<='9') { hy=(hy<<1)+(hy<<3)+cc-'0'; cc=getchar(); } } struct tree { tree *f,*pp,*c[2]; int siz,minv,a; bool flip; int d(){return f->c[1]==this;} void sc(tree *x,int d){(c[d]=x)->f=this;} }nil ,*ro ,*edge ; struct yy { int tim,num; bool ops; }f[400400]; bool cmp(yy a,yy b) { return a.tim<b.tim; } tree *newtree(int k) { nil[++cnt]=nil[0]; nil[cnt].a=nil[cnt].minv=k; return nil+cnt; } void up(tree *x) { x->siz=x->c[0]->siz+x->c[1]->siz+1; x->minv=x->a; if(x->c[0]!=nil) x->minv=min(x->minv,x->c[0]->minv); if(x->c[1]!=nil) x->minv=min(x->minv,x->c[1]->minv); } void down(tree *x) { if(!x->flip) return; swap(x->c[0],x->c[1]); if(x->c[0]!=nil) x->c[0]->flip^=1; if(x->c[1]!=nil) x->c[1]->flip^=1; x->flip=0; } void work(tree *x) { if(x->f!=nil) work(x->f); down(x); } void zig(tree *x) { int d=x->d(); tree *y=x->f; y->sc(x->c[!d],d); if(y->f!=nil) y->f->sc(x,y->d()); else x->f=nil; x->sc(y,!d); up(y); up(x); x->pp=y->pp; y->pp=nil; } void splay(tree *x) { work(x); for(tree *y;x->f!=nil;) { y=x->f; if(y->f!=nil) (x->d() ^ y->d()) ? zig(x) : zig(y); zig(x); } } void Access(tree *x) { tree *y=nil; while(x!=nil) { splay(x); if(x->c[1]!=nil) { x->c[1]->f=nil; x->c[1]->pp=x; } x->c[1]=y; if(y!=nil) y->f=x; y->pp=nil; up(x); y=x; x=x->pp; } } void Evert(tree *x) { Access(x); splay(x); x->flip^=1; } tree *find(tree *x) { Access(x); splay(x); while(x->c[0]!=nil) { x=x->c[0]; down(x); } splay(x); return x; } tree *Getmin(tree *x) { for(;;) { if(x->a==x->minv) break; if(x->c[0]->minv==x->minv) x=x->c[0]; else x=x->c[1]; down(x); } splay(x); return x; } void Link(tree *x,tree *y) { Evert(y); y->pp=x; } void Cut(tree *x,tree *y) { Evert(x); Access(y); splay(y); y->c[0]->f=nil; y->c[0]=nil; up(y); } int main() { nil->a=nil->minv=oo; nil->c[0]=nil->c[1]=nil->pp=nil->f=nil; cin>>n>>m>>t; for(int i=1;i<=n;i++) ro[i]=newtree(oo); for(int i=1;i<=m;i++) { read(x[i]); read(y[i]); read(op[i]); read(ed[i]); cur++; f[cur].tim=op[i]; f[cur].num=i; f[cur].ops=0; cur++; f[cur].tim=ed[i]; f[cur].num=i; f[cur].ops=1; edge[i]=newtree(ed[i]); } sort(f+1,f+cur+1,cmp); for(int i=1;i<=cur;i++) { int hy=f[i].num; if(f[i].ops) { if(in[hy]) { Cut(edge[hy],ro[x[hy]]); Cut(edge[hy],ro[y[hy]]); in[hy]=false; } } else { if(find(ro[x[hy]])!=find(ro[y[hy]])) { Link(ro[x[hy]],edge[hy]); Link(ro[y[hy]],edge[hy]); in[hy]=1; } else { Evert(ro[x[hy]]); Access(ro[y[hy]]); splay(ro[x[hy]]); int len=(ro[x[hy]]->siz+1)/2; int early=ro[x[hy]]->minv; tree *tu=Getmin(ro[x[hy]]); if(early<ed[hy]) { int zy=(tu-nil)-n; Cut(tu,ro[x[zy]]); Cut(tu,ro[y[zy]]); in[zy]=false; Link(edge[hy],ro[x[hy]]); Link(edge[hy],ro[y[hy]]); in[hy]=true; } early=min(early,ed[hy]); if(len%2==1) { ans[f[i].tim+1]++; ans[early+1]--; } } } } for(int i=1;i<=t;i++) { ans[i]+=ans[i-1]; if(ans[i]==0) printf("Yes\n"); else printf("No\n"); } return 0; }
相关文章推荐
- bzoj 2002 link cut tree(LCT)
- [BZOJ2002] [HNOI2010] 弹飞绵羊 - Link-Cut-Tree (LCT)
- BZOJ 2002 弹飞绵羊 Link-Cut-Tree(LCT)
- BZOJ 2002 弹飞绵羊 Link-Cut-Tree(LCT)
- BZOJ 2049 洞穴勘测 Link-Cut-Tree(LCT)
- LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板
- Link-Cut-Tree:【BZOJ2631】Tree
- BZOJ 2243(Link Cut Tree解法)
- 动态树 LCT(Link-Cut-Tree)--入门教程
- bzoj 2002 LinkCutTree
- BZOJ 3091 城市旅行 Link-Cut-Tree
- BZOJ 2594 Wc2006 水管局长数据加强版 Link-Cut-Tree
- BZOJ 2555 Substring 后缀自动机+Link-Cut-Tree
- BZOJ 2631: tree Link_Cut_Tree
- BZOJ-2631 tree Link-Cut-Tree
- bzoj 2594: [Wc2006]水管局长数据加强版 link cut tree
- Link-Cut-Tree:【BZOJ2002】弹飞绵羊
- [bzoj2049][Sdoi2008]Cave 洞穴勘测 Link-Cut-Tree
- [BZOJ 3669][NOI 2014]魔法森林(Link-Cut Tree)
- BZOJ 3306 树 Link-Cut-Tree+set