• 数据结构(并查集||树链剖分):HEOI 2016 tree


    【注意事项】


    为了体现增强版,题目限制和数据范围有所增强:

    时间限制:1.5s

    内存限制:128MB

    对于15% 的数据,1<=N,Q<=1000.

    对于35% 的数据,1<=N,Q<=10000.

    对于50% 的数据,1<=N,Q<=100000,且数据均为官方数据.

    对于100% 的数据,1<=N,Q<=1000000.

    请注意常数因子对于程序运行的影响。

      并查集很简单,并查集就是倒序处理,表示删除一个点的标记,删除后不会再加回来,删完后,合并当前点与其father的集合,根为father的原来的根,具体看代码……

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 using namespace std;
     6 const int N=1000010;
     7 int cnt,fir[N],to[N*2],nxt[N*2];
     8 void addedge(int a,int b){
     9     nxt[++cnt]=fir[a];
    10     to[fir[a]=cnt]=b;
    11 }
    12 int fa[N],vis[N],pre[N];
    13 int qr[N],tp[N],ans[N];
    14 void DFS(int x){
    15     for(int i=fir[x];i;i=nxt[i])
    16         if(to[i]!=pre[x]){
    17             pre[to[i]]=x;
    18             DFS(to[i]);
    19         }
    20 }
    21 void DFS(int x,int f){
    22     fa[x]=f;
    23     for(int i=fir[x];i;i=nxt[i])
    24         if(to[i]!=pre[x]){
    25             if(!vis[to[i]])DFS(to[i],f);
    26             else DFS(to[i],to[i]);
    27         }
    28 }
    29 int Find(int x){return fa[x]==x?x:fa[x]=Find(fa[x]);}
    30 int n,Q;char op[5];
    31 int main(){
    32     freopen("tree++.in","r",stdin);
    33     freopen("tree++.out","w",stdout);
    34     int sz=32<<20;
    35     char*p=(char*)malloc(sz)+sz;
    36     __asm__("movl %0,%%esp
    "::"r"(p));
    37     scanf("%d%d",&n,&Q);
    38     for(int i=1,a,b;i<n;i++){
    39         scanf("%d%d",&a,&b);
    40         addedge(a,b);
    41         addedge(b,a);
    42     }DFS(1);
    43     for(int i=1;i<=Q;i++){
    44         scanf("%s%d",op,&qr[i]);
    45         tp[i]=op[0]=='Q'?0:1;
    46     }
    47     vis[1]=1;
    48     for(int i=1;i<=Q;i++)
    49         if(tp[i])vis[qr[i]]+=1;
    50     DFS(1,1);
    51     for(int i=Q;i>=1;i--){
    52         if(!tp[i])
    53             ans[i]=Find(qr[i]);
    54         else{
    55             if(!--vis[qr[i]]){
    56                 int x=qr[i];
    57                 fa[x]=Find(pre[x]);
    58             }
    59         }
    60     }
    61     for(int i=1;i<=Q;i++)
    62         if(!tp[i])printf("%d
    ",ans[i]);
    63     return 0;
    64 }

      树链剖分很好想,但慢了些。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <cstdlib>
     5 #include <ctime>
     6 using namespace std;
     7 const int N=1000010;
     8 int cnt,fir[N],nxt[N*2],to[N*2];
     9 void addedge(int a,int b){
    10     nxt[++cnt]=fir[a];to[fir[a]=cnt]=b;
    11     nxt[++cnt]=fir[b];to[fir[b]=cnt]=a;
    12 }
    13 int sz[N],son[N],fa[N],dep[N];
    14 void DFS(int x){sz[x]=1;
    15     for(int i=fir[x];i;i=nxt[i])
    16         if(to[i]!=fa[x]){
    17             dep[to[i]]=dep[fa[to[i]]=x]+1;
    18             DFS(to[i]);sz[x]+=sz[to[i]];
    19             if(sz[son[x]]<sz[to[i]])son[x]=to[i];
    20         }
    21 }
    22 int tot,id[N],rid[N],top[N];
    23 void DFS(int x,int tp){
    24     top[rid[id[x]=++tot]=x]=tp;
    25     if(son[x])DFS(son[x],tp);
    26     for(int i=fir[x];i;i=nxt[i])
    27         if(to[i]!=fa[x]&&to[i]!=son[x])
    28             DFS(to[i],to[i]);
    29 }
    30 int sum[N*4],pos[N*4];
    31 #define mid (l+r>>1)
    32 void Push_up(int x){
    33     sum[x]=sum[x<<1]+sum[x<<1|1];
    34     if(sum[x]==0)pos[x]=0;
    35     if(sum[x<<1|1])pos[x]=pos[x<<1|1];
    36     else pos[x]=pos[x<<1];
    37 }
    38 void Update(int x,int l,int r,int g){
    39     if(l==r){pos[x]=rid[l];sum[x]+=1;return;}
    40     if(mid>=g)Update(x<<1,l,mid,g);
    41     else Update(x<<1|1,mid+1,r,g);
    42     Push_up(x);
    43 }
    44 
    45 int Query(int x,int l,int r,int a,int b){
    46     //if(!sum[x])return 0;
    47     if(l>=a&&r<=b)return pos[x];int ret=0;
    48     if(mid<b)ret=Query(x<<1|1,mid+1,r,a,b);
    49     if(!ret&&mid>=a)ret=Query(x<<1,l,mid,a,b);
    50     return ret;    
    51 }
    52 
    53 int tag[N],n,Q,x;
    54 int Solve(int x){
    55     while(x){
    56         int d=Query(1,1,n,id[top[x]],id[x]);
    57         if(d)return d;x=fa[top[x]];
    58     }
    59     return 0;
    60 }
    61 char op[5],c;
    62 void read(int &x){
    63     x=0;while(c=getchar(),c>'9'||c<'0');
    64     while(x=x*10+(c^48),c=getchar(),c>='0'&&c<='9');    
    65 }    
    66 int main(){
    67     freopen("tree++.in","r",stdin);
    68     freopen("tree++.out","w",stdout); 
    69     read(n);read(Q);
    70     int size = 32 << 20; // 256MB  
    71     char *p = (char*)malloc(size) + size;  
    72     __asm__("movl %0, %%esp
    " :: "r"(p));
    73     for(int i=1,a,b;i<n;i++){
    74         read(a);read(b);
    75         addedge(a,b);
    76     }
    77     DFS(1);DFS(1,1);
    78     Update(1,1,n,1);tag[1]=1;
    79     while(Q--){
    80         scanf("%s",op);read(x);
    81         if(op[0]=='C'){
    82             if(tag[x])continue;
    83             Update(1,1,n,id[x]);
    84             tag[x]=1;
    85         }
    86         else{
    87             printf("%d
    ",Solve(x));
    88         }
    89     }
    90     //printf("%.2f
    ",1.0*clock()/CLOCKS_PER_SEC);
    91     return 0;
    92 }
  • 相关阅读:
    [SCOI2013]火柴棍数字(背包)
    [NOI2015]品酒大会
    后缀数组小结
    [POI2009]Slw
    [POI2009]Wie
    [POI2008]账本BBB
    ant语法和规范
    使用Hudson进行持续集成
    gnu make
    可信执行环境(TEE)介绍
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5886174.html
Copyright © 2020-2023  润新知