• 数据结构(并查集||树链剖分):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 }
  • 相关阅读:
    What is the difference between google tag manager and google analytics?
    GetService<IMessageBoxService>() returned null.
    Using Google Consent Mode to Adjust Tag Behavior Based on Consent
    what are the values in _ga cookie?
    DEP019 System table or view is deprecated
    How to set the Google Analytics cookie only after another consent cookie is set and "true"?
    Tag Manager and gtag.js
    Using the OptanonWrapper Callback Function
    elk7.15.1版本收集nginx日志并用kibana图形化分析日志
    ELK分析Nginx日志和可视化展示
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5886174.html
Copyright © 2020-2023  润新知