bzoj 3123: [Sdoi2013]森林
Posted ws_ccd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3123: [Sdoi2013]森林相关的知识,希望对你有一定的参考价值。
如果题号没记错的话,2588是一个树上的主席树查询。这个题就是多了个合并而已。每一次都把小的合并到大的上就好了(所谓启发式2333)
(主席树真是个好东西2333)
(上部分为本蒟蒻不知道为什么RE到死都RE的代码,,,挖坑)
(个人感觉主席树这种东西里离散不离散没什么区别的(常数而已),毕竟是log的,大个几次方就是多了个常数而已)
1 /*#include<bits/stdc++.h> 2 #define N 100005 3 #define M 40000005 4 #define LL long long 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 inline int ra() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} 11 while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 12 return x*f; 13 } 14 int sz,n,m,Q,T,cnt,ans; 15 int ls[M],rs[M],sum[M],root[N],head[N]; 16 int size[N],belong[N],fa[N][20],vis[N],deep[N],a[N],hash[N],num[N],tot; 17 struct node{int to,next;}e[N<<2]; 18 void ins(int x, int y){e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt;} 19 int find(int x) 20 { 21 int l=1,r=tot; 22 while (l<=r) 23 { 24 int mid=l+r>>1; 25 if (hash[mid]==x) return mid; 26 else if (hash[mid]<x) l=mid+1; 27 else r=mid-1; 28 } 29 } 30 void insert(int l, int r, int x, int &y, int v) 31 { 32 y=++sz; 33 sum[y]=sum[x]+1; 34 ls[y]=ls[x]; rs[y]=rs[x]; 35 if (l==r) return; 36 int mid=l+r>>1; 37 if (v<=mid) insert(l,mid,ls[x],ls[y],v); 38 else insert(mid+1,r,rs[x],rs[y],v); 39 } 40 void dfs(int x, int bl) 41 { 42 for (int i=1; i<=16; i++) 43 fa[x][i]=fa[fa[x][i-1]][i-1]; 44 insert(1,tot,root[fa[x][0]],root[x],find(a[x])); 45 belong[x]=bl; size[belong[x]]++; 46 for (int i=head[x];i;i=e[i].next) 47 { 48 if (e[i].to==fa[x][0]) continue; 49 deep[e[i].to]=deep[x]+1; 50 fa[e[i].to][0]=x; 51 dfs(e[i].to,bl); 52 } 53 } 54 int getlca(int x, int y) 55 { 56 if (deep[x]<deep[y]) swap(x,y); 57 int t=deep[x]-deep[y]; 58 for (int i=0; i <=16; i++) 59 if (t&(1<<i)) x=fa[x][i]; 60 for (int i=16; i>=0; i--) 61 if (fa[x][i]!=fa[y][i]) 62 x=fa[x][i],y=fa[y][i]; 63 if (x==y) return x; 64 return fa[x][0]; 65 } 66 void query(int x, int y, int k) 67 { 68 int a1=root[x],b=root[y],z=getlca(x,y),w=a[z]; 69 int c=root[z]; 70 int l=1,r=tot; 71 while (l!=r) 72 { 73 int mid=l+r>>1; 74 int tmp=sum[ls[a1]]+sum[ls[b]]-2*sum[ls[c]]+(w>=l && w<=mid); 75 if (tmp>=k) r=mid,a1=ls[a1],b=ls[b],c=ls[c]; 76 else k-=tmp,l=mid+1,a1=rs[a1],b=rs[b],c=rs[c]; 77 } 78 printf("%d\n",ans=hash[l]); 79 } 80 void merge(int x, int y) 81 { 82 if (size[belong[x]]<size[belong[y]]) swap(x,y); 83 fa[y][0]=x; deep[y]=deep[x]+1; ins(x,y); ins(y,x); 84 dfs(y,belong[x]); 85 } 86 int main() 87 { 88 T=ra(); int ti=0; 89 while (T--) 90 { 91 n=ra(); m=ra(); Q=ra(); 92 for (int i=1; i<=n; i++) num[i]=a[i]=ra(); 93 sort(num+1,num+n+1); 94 hash[++tot]=num[1]; 95 for (int i=2; i<=n; i++) 96 if (num[i]!=num[i-1]) 97 hash[++tot]=num[i]; 98 for (int i=1; i<=m; i++) 99 { 100 int x=ra(),y=ra(); 101 ins(x,y); ins(y,x); 102 } 103 for (int i=1; i<=n; i++) 104 if (!fa[i][0]) dfs(i,i); 105 for (int i=1; i<=Q; i++) 106 { 107 char s[3]; scanf("%s",s); 108 int x=ra()^ans,y=ra()^ans; 109 if (s[0]==‘Q‘) 110 { 111 int k=ra()^ans; 112 query(x,y,k); 113 } 114 else merge(x,y); 115 } 116 } 117 return 0; 118 }*/ 119 120 121 122 123 124 125 126 127 128 #include<bits/stdc++.h> 129 #define N 100005 130 #define M 10000005 131 #define LL long long 132 #define inf 0x3f3f3f3f 133 using namespace std; 134 inline int ra() 135 { 136 int x=0,f=1; char ch=getchar(); 137 while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} 138 while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 139 return x*f; 140 } 141 int n,m,T,ans,cnt,tot,sz,testcase,query_sum; 142 int f[N],size[N],deep[N],a[N],num[N],hash[N],root[N],fa[N][17]; 143 int ls[M],rs[M],sum[M]; 144 int head[N],list[N<<1],next[N<<1]; 145 struct node{ 146 int to,next; 147 }e[N<<1]; 148 int Find(int x) 149 { 150 int l=1,r=tot; 151 while (l<=r) 152 { 153 int mid=l+r>>1; 154 if (hash[mid]==x) return mid; 155 else if (hash[mid]<x) l=mid+1; 156 else r=mid-1; 157 } 158 } 159 void insert(int x, int y) 160 { 161 e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt; 162 } 163 int find(int i) 164 { 165 if (!f[i]) size[i]=1,f[i]=i; 166 if (f[i]==i) return i; 167 return f[i]=find(f[i]); 168 } 169 void merge(int x, int y) 170 { 171 int p=find(x),q=find(y); 172 f[p]=q; size[q]+=size[p]; 173 } 174 void update(int l, int r, int x, int &y, int v) 175 { 176 y=++sz; 177 ls[y]=ls[x]; rs[y]=rs[x]; sum[y]=sum[x]+1; 178 if (l==r) return; 179 int mid=l+r>>1; 180 if (v<=mid) update(l,mid,ls[x],ls[y],v); 181 else update(mid+1,r,rs[x],rs[y],v); 182 } 183 void dfs(int x) 184 { 185 for (int i=1; i<=16; i++) 186 fa[x][i]=fa[fa[x][i-1]][i-1]; 187 update(1,tot,root[fa[x][0]],root[x],Find(a[x])); 188 for (int i=head[x];i;i=e[i].next) 189 { 190 if (e[i].to==fa[x][0]) continue; 191 deep[e[i].to]=deep[x]+1; 192 fa[e[i].to][0]=x; 193 dfs(e[i].to); 194 } 195 } 196 int lca(int x, int y) 197 { 198 if (deep[x]<deep[y]) swap(x,y); 199 int t=deep[x]-deep[y]; 200 for (int i=0; (1<<i)<=t; i++) 201 if ((1<<i)&t) x=fa[x][i]; 202 for (int i=16; i>=0; i--) 203 if (fa[x][i]!=fa[y][i]) 204 x=fa[x][i],y=fa[y][i]; 205 return x==y?x:fa[x][0]; 206 } 207 int query(int a, int b, int c, int d, int k) 208 { 209 int l=1,r=tot; 210 while (l!=r) 211 { 212 int mid=l+r>>1; 213 int tmp=sum[ls[a]]+sum[ls[b]]-sum[ls[c]]-sum[ls[d]]; 214 if (tmp>=k) r=mid,a=ls[a],b=ls[b],c=ls[c],d=ls[d]; 215 else l=mid+1,k-=tmp,a=rs[a],b=rs[b],c=rs[c],d=rs[d]; 216 } 217 return l; 218 } 219 int main() 220 { 221 int textcast=ra(); 222 n=ra(); m=ra(); T=ra(); 223 for (int i=1; i<=n; i++) a[i]=num[i]=ra(); 224 sort(num+1,num+n+1); 225 hash[++tot]=num[1]; 226 for (int i=2; i<=n; i++) 227 if (num[i]!=num[i-1]) hash[++tot]=num[i]; 228 for (int i=1; i<=m; i++) 229 { 230 int x=ra(),y=ra(); 231 insert(x,y); insert(y,x); merge(x,y); 232 } 233 for (int i=1; i<=n; i++) 234 if (!fa[i][0]) dfs(i); 235 while (T--) 236 { 237 char s[3]; scanf("%s",s); 238 int a=ra()^ans,b=ra()^ans; 239 if (s[0]==‘Q‘) 240 { 241 int k=ra()^ans; 242 int c=lca(a,b); 243 int d=fa[c][0]; 244 printf("%d\n",ans=hash[query(root[a],root[b],root[c],root[d],k)]); 245 } 246 else 247 { 248 int p=find(a),q=find(b); 249 if (size[p]>size[q]) swap(a,b); 250 fa[a][0]=b; deep[a]=deep[b]+1; 251 dfs(a); 252 merge(a,b); 253 insert(a,b); insert(b,a); 254 } 255 } 256 return 0; 257 }
以上是关于bzoj 3123: [Sdoi2013]森林的主要内容,如果未能解决你的问题,请参考以下文章
主席树 启发式合并bzoj3123: [Sdoi2013]森林