标签:hide algorithm ++ ring etc std 传递 观点 har
#include <stdio.h> #include <algorithm> #include <cstring> const int maxn=200000; typedef std:complex<double> com;//typedef 真实放前 define 真实放后 com eps[maxn],ieps[maxn];//单位根以及其共轭 //再次注意,我们用IDFT求的都是2^m的次数的多项式,并且假定n=2m inline void trans(int n,int x[],int w[])//使用复数还是共轭 { for(int i=0,j=0;i!=n;i++)//i是正常加法,如果说两个没有换过,我们换一下 { if(i<j) swap(x[i],x[j]); for(int l=n>>1;(j^=l)<l;l>>=1);//每次都是算0-》1是大于l而1->0小于l } }
然后,就让我们进入LCT的世界
首先 show the code
#include <stdio.h> #include <algorithm> #include <cstring> #include <cctype> using namespace std; const int maxn=100200; struct Node { int lx,rx,fa,rev; #define l(x) t[x].lx #define r(x) t[x].rx #define rev(x) t[x].rev #define fa(x) t[x].fa }t[maxn]; int n,m; int que[maxn],top; inline int read() { int x=0,b=1;char c=getchar(); while(!isdigit(c)) b=c==‘-‘?-1:1,c=getchar(); while(isdigit(c)) x=x*10+c-‘0‘,c=getchar(); return x*b; } inline void down(int x) { if(rev(x)) { swap(l(x),r(x)); if(l(x)) rev(l(x))^=1; if(r(x)) rev(r(x))^=1; rev(x)=0; } } inline int isroot(int x) { if(!fa(x)) return true; return x!=l(fa(x))&&x!=r(fa(x)); } inline void rot(int x)//因为我们只在splay当中rot,并且已经把涉及的节点全部都down了一遍了,就不用再在里面进行判断了 { int y=fa(x),z=fa(y),b=x==l(y)?r(x):l(x); if(z&&!isroot(y)) (y==l(z)?l(z):r(z))=x;//这里要设置z的左右儿子,根据lct的性质,我们设置左右儿子时,可能父亲左右儿子都是自己,所以更要小心 fa(x)=z,fa(y)=x;if(b) b?fa(b)=y:0;//不知道这一步有没有影响 // //这一步果然有影响,因为我们判断isroot的条件就是他的fa(X)或者他的fa左右儿子都不是他,但是先提前设置fa(y)=x就会导致爆炸 //所以,以后再次编写代码的时候一定要考虑好顺序性问题 //好习惯,我们可以将有逻辑顺序性的代码存放在一起便于查看 //总结over if(x==l(y)) r(x)=y,l(y)=b; else l(x)=y,r(y)=b; return; } inline int war(int x) { return r(fa(x))==x; } inline void splay(int x) { que[top=0]=x; for(int y=x;!isroot(y);y=fa(y)) que[++top]=fa(y);//从x直到根节点上面的路径都要被保存//在注意,我们这里存入que的是fa(y)而不是y为什么呢 for(int i=top;i>=0;i--) down(que[i]);//懒标记的性质,从上往下传递标记 while(!isroot(x)) { if(!isroot(fa(x)))//为什么是判断isrootfa(x)而不是我们之前的fa[fa[x]]!=tar rot(war(fa(x))==war(x)?fa(x):x); rot(x); } return ; } inline void access(int x) { for(int y=0;x;y=x,x=fa(x)) { splay(x);r(x)=y;//右边连接到上一个x,相当于将x的整棵树和y右子树做了个替换 if(y) fa(y)=x; } } inline int getroot(int x) { access(x);splay(x); while(down(x),l(x)){//先down后找 x=l(x); } splay(x);return x; } inline void makeroot(int x) { access(x);splay(x); rev(x)^=1; } inline void bulid(int x,int y) { makeroot(x);fa(x)=y; return; } inline void Delete(int x,int y) { makeroot(x);access(y);splay(y); l(y)=0;fa(x)=0;return;//在平衡树当中直接操作 } int main() { n=read();m=read(); for(int i=1;i<=m;i++) { char s[200]; scanf("%s",s); if(s[0]==‘Q‘) { //printf("1\n"); if(getroot(read())==getroot(read())) printf("Yes\n"); else printf("No\n"); } else if(s[0]==‘C‘) bulid(read(),read());//printf("2\n"); else Delete(read(),read()); } return 0; }
动态树(准确说是维护森林)之一,支持连边,断边,求链上权值和等操作。
标签:hide algorithm ++ ring etc std 传递 观点 har
原文地址:https://www.cnblogs.com/ILHYJ/p/13723673.html