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]森林的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3123 [Sdoi2013]森林

BZOJ 3123 SDOI2013 森林

bzoj3123: [Sdoi2013]森林

主席树 启发式合并bzoj3123: [Sdoi2013]森林

BZOJ 3123 [Sdoi2013]森林 主席树启发式合并

[bzoj3123] [SDOI2013]森林 主席树+启发式合并+LCT