zoukankan      html  css  js  c++  java
  • [bzoj3123]森林

    首先对于询问操作可以使用可持久化线段树来维护,对于连边操作对于两颗树中选取较小的树暴力练到另一个点上,点数可以用并查集然后只修改根的点数即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mid (l+r>>1)
     4 #define N 100001
     5 struct ji{
     6     int nex,to;
     7 }edge[N<<1];
     8 int E,V,n,m,t,x,y,z,ans,a[N],ff[N],sum[N],f[21][N],head[N],sz[20*N],b[N],son[2][20*N],s[N],r[N],vis[N];
     9 char s1[11];
    10 void add(int x,int y){
    11     edge[E].nex=head[x];
    12     edge[E].to=y;
    13     head[x]=E++;
    14 }
    15 int find(int k){
    16     if (k==ff[k])return k;
    17     return ff[k]=find(ff[k]);
    18 }
    19 int ne(int &k){
    20     if (!k)k=++V;
    21     return k;
    22 }
    23 int lca(int x,int y){
    24     if (s[x]<s[y])swap(x,y);
    25     for(int i=20;i>=0;i--)
    26         if (s[f[i][x]]>=s[y])x=f[i][x];
    27     if (x==y)return x;
    28     for(int i=20;i>=0;i--)
    29         if (f[i][x]!=f[i][y]){
    30             x=f[i][x];
    31             y=f[i][y];
    32         }
    33     return f[0][x];
    34 }
    35 void merge(int x,int y){
    36     ff[find(x)]=find(y);
    37     sum[find(y)]+=sum[find(x)];
    38 }
    39 void update(int k1,int k2,int l,int r,int x){
    40     sz[k1]=sz[k2]+1;
    41     if (l==r)return;
    42     int p=(x>mid);
    43     son[p^1][k1]=son[p^1][k2];
    44     update(ne(son[p][k1]),son[p][k2],l+(mid-l+1)*p,mid+(r-mid)*p,x);
    45 }
    46 int query(int l,int r,int x,int a,int b,int c,int d){
    47     if (l==r)return l;
    48     int t=sz[son[0][a]]+sz[son[0][b]]-sz[son[0][c]]-sz[son[0][d]],p=(x>t);
    49     return query(l+(mid-l+1)*p,mid+(r-mid)*p,x-p*t,son[p][a],son[p][b],son[p][c],son[p][d]);
    50 }
    51 void dfs(int k,int fa){
    52     vis[k]=1;
    53     s[k]=s[f[0][k]=fa]+1;
    54     for(int i=1;i<=20;i++)f[i][k]=f[i-1][f[i-1][k]];
    55     update(ne(r[k]),r[fa],1,m,a[k]);
    56     for(int i=head[k];i!=-1;i=edge[i].nex)
    57         if (edge[i].to!=fa)dfs(edge[i].to,k);
    58 }
    59 int main(){
    60     scanf("%*d%d%d%d",&n,&m,&t);
    61     memset(head,-1,sizeof(head));
    62     for(int i=1;i<=n;i++){
    63         scanf("%d",&a[i]);
    64         ff[i]=i;
    65         sum[i]=1;
    66     }
    67     for(int i=1;i<=m;i++){
    68         scanf("%d%d",&x,&y);
    69         add(x,y);
    70         add(y,x);
    71         merge(x,y);
    72     }
    73     memcpy(b,a,sizeof(b));
    74     sort(b+1,b+n+1);
    75     m=unique(b+1,b+n+1)-b-1;
    76     for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+m+1,a[i])-b;
    77     for(int i=1;i<=n;i++)
    78         if (!vis[i])dfs(i,0);
    79     while (t--){
    80         scanf("%s%d%d",s1,&x,&y);
    81         x^=ans;
    82         y^=ans;
    83         if (s1[0]=='Q'){
    84             scanf("%d",&z);
    85             printf("%d\n",ans=b[query(1,m,z^ans,r[x],r[y],r[lca(x,y)],r[f[0][lca(x,y)]])]);
    86         }
    87         if (s1[0]=='L'){
    88             if (sum[find(x)]>sum[find(y)])swap(x,y);
    89             add(x,y);
    90             add(y,x);
    91             merge(x,y);
    92             dfs(x,y);
    93         }
    94     }
    95 }
    View Code
  • 相关阅读:
    大型站点技术架构PDF阅读笔记(一):
    【大话QT之十三】系统软件自己主动部署实现方案
    VS编译duilib项目时候的错误解决方法整理
    Missing iOS Distribution signing identity for …, 在打包的时候发现证书过期了。
    Django项目国际化
    Codeforces Round #297 (Div. 2) 525D Arthur and Walls(dfs)
    BZOJ 2209: [Jsoi2011]括号序列 [splay 括号]
    NOIP2016DAY1题解
    清北学堂入学测试P4751 H’s problem(h)
    BZOJ 3173: [Tjoi2013]最长上升子序列 [splay DP]
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249760.html
Copyright © 2011-2022 走看看