zoukankan      html  css  js  c++  java
  • [bzoj3123][洛谷P3302] [SDOI2013]森林(树上主席树+启发式合并)

    传送门

    突然发现好像没有那么难……https://blog.csdn.net/stone41123/article/details/78167288

    首先有两个操作,一个查询,一个连接

    查询的话,直接在树上建主席树

    然后难点在于连接

    用启发式合并就可以了(想了半天都没想出来)

    每次合并时,我们把小的树接到大的上,然后dfs一遍小的树,更新信息

    然后注意数组……别太小也别太大……(被数组大小坑了好几次提交)

      1 //minamoto
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
      5 char buf[1<<21],*p1=buf,*p2=buf;
      6 inline int read(){
      7     #define num ch-'0'
      8     char ch;bool flag=0;int res;
      9     while(!isdigit(ch=getc()))
     10     (ch=='-')&&(flag=true);
     11     for(res=num;isdigit(ch=getc());res=res*10+num);
     12     (flag)&&(res=-res);
     13     #undef num
     14     return res;
     15 }
     16 char obuf[1<<24],*o=obuf;
     17 void print(int x){
     18     if(x>9) print(x/10);
     19     *o++=x%10+48;
     20 }
     21 const int N=80005,M=N*200;
     22 int ver[N<<2],Next[N<<2],head[N];
     23 int a[N],fa[N],sz[N],b[N];
     24 int n,m,tot,q,size,ans;
     25 void add(int u,int v){
     26     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
     27     ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
     28 }
     29 int L[M],R[M],sum[M],rt[N],cnt;
     30 void update(int last,int &now,int l,int r,int x){
     31     sum[now=++cnt]=sum[last]+1;
     32     if(l==r) return;
     33     int mid=(l+r)>>1;
     34     if(x<=mid) R[now]=R[last],update(L[last],L[now],l,mid,x);
     35     else L[now]=L[last],update(R[last],R[now],mid+1,r,x);
     36 }
     37 int query(int u,int v,int lca,int lca_fa,int l,int r,int k){
     38     if(l>=r) return l;
     39     int x=sum[L[v]]+sum[L[u]]-sum[L[lca]]-sum[L[lca_fa]];
     40     int mid=(l+r)>>1;
     41     if(x>=k) return query(L[u],L[v],L[lca],L[lca_fa],l,mid,k);
     42     else return query(R[u],R[v],R[lca],R[lca_fa],mid+1,r,k-x);
     43 }
     44 inline int hash(int x){
     45     return lower_bound(b+1,b+1+size,x)-b;
     46 }
     47 int ff(int x){
     48     return fa[x]==x?x:fa[x]=ff(fa[x]);
     49 }
     50 int st[N][17],d[N],vis[N];
     51 void dfs(int u,int father,int root){
     52     st[u][0]=father;
     53     for(int i=1;i<=16;++i)
     54     st[u][i]=st[st[u][i-1]][i-1];
     55     ++sz[root];
     56     d[u]=d[father]+1;
     57     fa[u]=root;
     58     vis[u]=1;
     59     update(rt[father],rt[u],1,size,hash(a[u]));
     60     for(int i=head[u];i;i=Next[i]){
     61         int v=ver[i];
     62         if(v==father) continue;
     63         dfs(v,u,root);
     64     }
     65 }
     66 int LCA(int x,int y){
     67     if(x==y) return x;
     68     if(d[x]<d[y]) swap(x,y);
     69     for(int i=16;i>=0;--i){
     70         if(d[st[x][i]]>=d[y]) x=st[x][i];
     71     }
     72     if(x==y) return x;
     73     for(int i=16;i>=0;--i){
     74         if(st[x][i]!=st[y][i])
     75         x=st[x][i],y=st[y][i];
     76     }
     77     return st[x][0];
     78 }
     79 int main(){
     80     //freopen("testdata.in","r",stdin);
     81     int t=read();
     82     n=read(),m=read(),q=read();
     83     for(int i=1;i<=n;++i)
     84     a[i]=b[i]=read(),fa[i]=i;
     85     sort(b+1,b+1+n);
     86     size=unique(b+1,b+1+n)-b-1;
     87     for(int i=1;i<=m;++i){
     88         int u=read(),v=read();
     89         add(u,v);
     90     }
     91     for(int i=1;i<=n;++i)
     92     if(!vis[i]) dfs(i,0,i);
     93     while(q--){
     94         char ch;int x,y;
     95         while(!isupper(ch=getc()));
     96         x=read()^ans,y=read()^ans;
     97         if(ch=='Q'){
     98             int k=read()^ans;
     99             int lca=LCA(x,y);
    100             ans=b[query(rt[x],rt[y],rt[lca],rt[st[lca][0]],1,size,k)];
    101             print(ans),*o++='
    ';
    102         }
    103         else{
    104             add(x,y);
    105             int u=ff(x),v=ff(y);
    106             if(sz[u]<sz[v]) swap(x,y),swap(u,v);
    107             dfs(y,x,u);
    108         }
    109     }
    110     fwrite(obuf,o-obuf,1,stdout);
    111     return 0;
    112 }
  • 相关阅读:
    HttpCookie类
    WebClient类
    最大流算法 ISAP 模板 和 Dinic模板
    拓扑序+dp Codeforces Round #374 (Div. 2) C
    二分 Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) D
    线段树 或者 并查集 Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C
    无源无汇有上下界的最大流
    并查集+bfs+暴力滑窗 Codeforces Round #356 (Div. 2) E
    dfs Codeforces Round #356 (Div. 2) D
    cookie+session
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9396807.html
Copyright © 2011-2022 走看看