bzoj 3123 [Sdoi2013]森林

Description

 

Input

第一行包含一个正整数testcase,表示当前测试数据的测试点编号。保证1≤testcase≤20。 
第二行包含三个整数N,M,T,分别表示节点数、初始边数、操作数。第三行包含N个非负整数表示 N个节点上的权值。 
 接下来 M行,每行包含两个整数x和 y,表示初始的时候,点x和点y 之间有一条无向边, 接下来 T行,每行描述一个操作,格式为“Q x y k”或者“L x y ”,其含义见题目描述部分。

Output

对于每一个第一类操作,输出一个非负整数表示答案。 
 
 

Sample Input

1
8 4 8
1 1 2 2 3 3 4 4
4 7
1 8
2 4
2 1
Q 8 7 3 Q 3 5 1
Q 10 0 0
L 5 4
L 3 2 L 0 7
Q 9 2 5 Q 6 1 6

Sample Output

2
2
1
4
2

HINT

 



对于第一个操作 Q 8 7 3,此时 lastans=0,所以真实操作为Q 8^0 7^0 3^0,也即Q 8 7 3。点8到点7的路径上一共有5个点,其权值为4 1 1 2 4。这些权值中,第三小的为 2,输出 2,lastans变为2。对于第二个操作 Q 3 5 1 ,此时lastans=2,所以真实操作为Q 3^2 5^2 1^2 ,也即Q 1 7 3。点1到点7的路径上一共有4个点,其权值为 1 1 2 4 。这些权值中,第三小的为2,输出2,lastans变为 2。之后的操作类似。 

 

 
 
思路:主席树+ 启发式暴力合并。 
时间复杂度$O(nlog^{2}n) $,空间复杂度$O(nlog^{2}n)$
 
  1 #include<bits/stdc++.h>
  2 using namespace std;  
  3 #define R register int
  4 #define rep(i,a,b) for(R i=a;i<=b;i++)  
  5 #define Rep(i,a,b) for(R i=a;i>=b;i--) 
  6 #define rp(i,x)    for(R i=H[x];i!=-1;i=E[i].nt)  
  7 #define ms(i,a)    memset(a,i,sizeof(a))  
  8 #define gc()       getchar() 
  9 #define mid        (l+r)/2
 10 template<class T>void read(T &x){
 11     x=0; char c=0; 
 12     while (!isdigit(c)) c=gc(); 
 13     while (isdigit(c)) x=x*10+(c^48),c=gc();  
 14 }
 15 int const N=80000+3;  
 16 int const M=10000000+3; 
 17 int H[N],cnt,sum,f[N],n,m,t,a[N],b[N],tot,last,c[N],sz[N];  
 18 int s[M],lc[M],rc[M],fa[N][20],vis[N],dep[N],rt[N];  
 19 struct Edge{
 20     int to,nt;  
 21 }E[N<<1];  
 22 void add(int a,int b){E[cnt]=(Edge){b,H[a]}; H[a]=cnt++; }
 23 int gf(int x){return x==f[x]?  x:f[x]=gf(f[x]); }
 24 int lca(int x,int y){
 25     if(dep[x]<dep[y]) swap(x,y);  
 26     int l=dep[x]-dep[y];  
 27     rep(i,0,19) if( l& (1<<i)) x=fa[x][i];  
 28     if(x==y) return x;  
 29     Rep(i,19,0) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];  
 30     return fa[x][0] ; 
 31 }
 32 void update(int t,int &now,int  l,int r,int p){
 33     now=++sum;  
 34     s[now]=s[t]+1;   
 35     lc[now]=lc[t]; rc[now]=rc[t];   
 36     if(l==r) return ;   
 37     if(p<=mid) update(lc[t],lc[now],l,mid,p); 
 38     else update(rc[t],rc[now],mid+1,r,p); 
 39 } 
 40  
 41 void dfs(int x,int fat){    
 42     fa[x][0]=fat;dep[x]=dep[fat]+1;vis[x]=1; 
 43     rep(i,1,19) fa[x][i]=fa[fa[x][i-1]][i-1];     
 44     update(rt[fat],rt[x],1,tot,c[x]);   
 45     rp(i,x){
 46         int v=E[i].to; 
 47         if(v==fat) continue;  
 48         dfs(v,x);  
 49     }
 50 }
 51 int query(int x,int y,int c,int cc,int l,int r,int z){  
 52     if(l==r) return b[l];  
 53     int num=s[lc[x]]+s[lc[y]]-s[lc[c]]-s[lc[cc]];  
 54     if(z<=num) return query(lc[x],lc[y],lc[c],lc[cc],l,mid,z); 
 55     else return query(rc[x],rc[y],rc[c],rc[cc],mid+1,r,z-num);  
 56 } 
 57 
 58 int solve(int x,int y,int z){
 59     int c=lca(x,y); 
 60     int cc=fa[c][0];   
 61     return query(rt[x],rt[y],rt[c],rt[cc],1,tot,z); 
 62 }
 63 int main(){
 64     int cas; read(cas);      
 65     read(n); read(m); read(t);  
 66     rep(i,1,n) read(a[i]),b[i]=a[i];  
 67     sort(b+1,b+n+1);   
 68     tot=unique(b+1,b+n+1)-b-1;  
 69     rep(i,1,n) c[i]=lower_bound(b+1,b+tot+1,a[i])-b; 
 70     ms(-1,H); 
 71     rep(i,1,n) f[i]=i,sz[i]=1;   
 72     while (m--){
 73         int x,y;  
 74         read(x); read(y); 
 75         add(x,y); add(y,x);
 76         int fx=gf(x); 
 77         int fy=gf(y);  
 78         f[fx]=fy; sz[fy]+=sz[fx];   
 79     }
 80     rep(i,1,n) if(!vis[i]) dfs(i,0);      
 81     while (t--){
 82         char s[2];  
 83         scanf("%s",s);  
 84         if(s[0]=='Q'){
 85             int x,y,k; 
 86             read(x);read(y); read(k);  
 87             x^=last; y^=last; k^=last;  
 88             printf("%d\n",last=solve(x,y,k));          
 89         }else {
 90             int x,y; read(x); read(y);    
 91             x^=last;y^=last;
 92             int fx=gf(x); 
 93             int fy=gf(y);  
 94             if(sz[fx]<sz[fy]) swap(x,y),swap(fx,fy);  
 95             sz[fx]+=fy;  f[fy]=fx;  
 96             dfs(y,x);  
 97             add(x,y);add(y,x);  
 98         } 
 99     }
100     return 0; 
101 }
102             
103     
104     
View Code

 

posted @ 2019-02-25 21:50  zjxxcn  阅读(129)  评论(0编辑  收藏  举报