题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3731
题解:
多了一个操作:删边。
如果x与fa[x]不在同一块,直接把这条边去掉即可。
否则 我们把x以下的点全部划入新的以x的根的块内,然后把b[fa[x]]往下的边断开并连到b[x]上。
这些实现的时候都很有技巧性,具体可以看代码。
然后发现代码长了就很容易忘打XX,而且心里还会产生程序很对的错觉。。。
不断调整块的大小最后调到了sqrt(10*n*logn)然后就rank1了。。。比写treap的快了。。。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 200000+5 14 #define maxm 100000+5 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define for4(i,k,x) for(int i=head[k][x],y=e[k][i].go;i;i=e[k][i].next,y=e[k][i].go) 23 #define mod 1000000007 24 using namespace std; 25 inline int read() 26 { 27 int x=0,f=1;char ch=getchar(); 28 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 29 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 30 return x*f; 31 } 32 struct rec 33 { 34 vector<int>a; 35 inline void insert(int x) 36 { 37 a.insert(lower_bound(a.begin(),a.end(),x+1),x); 38 } 39 inline void erase(int x) 40 { 41 a.erase(lower_bound(a.begin(),a.end(),x)); 42 } 43 inline void modify(int x,int y) 44 { 45 erase(x);insert(y); 46 } 47 inline int query(int x) 48 { 49 return a.size()-(upper_bound(a.begin(),a.end(),x)-a.begin()+1)+1; 50 } 51 }s[maxn]; 52 int n,m,ans,size,cnt,top[maxn],tot[2],head[2][maxn],a[maxn],fa[2][maxn],b[maxn],c[maxn],d[maxn]; 53 struct edge{int go,next;}e[2][3*maxn]; 54 inline void add(int k,int x,int y) 55 { 56 e[k][++tot[k]]=(edge){y,head[k][x]};head[k][x]=tot[k]; 57 } 58 inline void dfs(int x) 59 { 60 for4(i,0,x)if(y!=fa[0][x]) 61 { 62 fa[0][y]=x; 63 if(s[b[x]].a.size()<size)s[b[y]=b[x]].insert(a[y]); 64 else top[b[y]=++cnt]=y,s[cnt].insert(a[y]),add(1,b[x],b[y]),fa[1][b[y]]=b[x]; 65 dfs(y); 66 } 67 } 68 inline void query2(int x,int w) 69 { 70 ans+=s[x].query(w); 71 for4(i,1,x)if(fa[1][y]==x)query2(y,w); 72 } 73 inline void query1(int x,int w) 74 { 75 if(a[x]>w)ans++; 76 for4(i,0,x)if(y!=fa[0][x]&&fa[0][y]==x){if(top[b[y]]==y)query2(b[y],w);else query1(y,w);} 77 } 78 inline void find(int x) 79 { 80 c[++c[0]]=x; 81 for4(i,0,x)if(y!=fa[0][x]&&fa[0][y]==x) 82 { 83 if(b[y]==b[x])find(y); 84 else d[++d[0]]=b[y]; 85 } 86 } 87 int main() 88 { 89 freopen("input.txt","r",stdin); 90 freopen("output.txt","w",stdout); 91 n=read(); 92 for1(i,n-1){int x=read(),y=read();add(0,x,y);add(0,y,x);} 93 for1(i,n)a[i]=read(); 94 s[b[1]=top[1]=cnt=1].insert(a[1]); 95 size=sqrt(10*n*log2(n)); 96 dfs(1); 97 m=read(); 98 while(m--) 99 { 100 int op=read(); 101 if(op==3) 102 { 103 int x=read()^ans; 104 if(b[x]!=b[fa[0][x]])fa[0][x]=0,fa[1][b[x]]=0; 105 else 106 { 107 find(x); 108 top[b[x]=++cnt]=x; 109 for1(i,c[0]) 110 { 111 s[b[fa[0][x]]].erase(a[c[i]]); 112 s[b[x]].insert(a[c[i]]); 113 b[c[i]]=b[x]; 114 } 115 for1(i,d[0])add(1,b[x],d[i]),fa[1][d[i]]=b[x]; 116 fa[0][x]=c[0]=d[0]=0; 117 } 118 } 119 else 120 { 121 int x=read()^ans,y=read()^ans; 122 if(op==0) 123 { 124 ans=0; 125 if(top[b[x]]!=x)query1(x,y); 126 else query2(b[x],y); 127 printf("%d ",ans); 128 }else if(op==1) 129 { 130 s[b[x]].modify(a[x],y); 131 a[x]=y; 132 }else if(op==2) 133 { 134 a[++n]=y;add(0,x,n);fa[0][n]=x; 135 if(s[b[x]].a.size()<size)s[b[n]=b[x]].insert(a[n]); 136 else top[b[n]=++cnt]=n,s[cnt].insert(a[n]),add(1,b[x],b[n]),fa[1][b[n]]=b[x]; 137 } 138 } 139 } 140 return 0; 141 }