• bzoj 1095: [ZJOI2007]Hide 捉迷藏


    2016-06-23

    这种题果然不是我这种智商的人可以做的。。

    网上两种做法,一种把树转化成括号序列  再用线段树维护好几个量(简直太神啦。。可惜蒟蒻看不懂)

    还有一种是 先把树每次点分治的重心连向上一层的重心,重建一棵树。再来三个堆,

    C.每个重心存所有子树到其距离
    B.每个重心存各个子树最大值,即子结点堆C的最大值
    A.全局一个堆,维护答案最大值,存每个堆B的最大值和次大值之和
    由于重建后树高log(n),所以时间可以保证。
      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cstdlib>
      6 #include<queue>
      7 #define M 100005
      8 #define ll long long
      9 using namespace std;
     10 ll read()
     11 {
     12     char ch=getchar();
     13     ll x=0,f=1;
     14     for(;ch<'0'||ch>'9';ch=getchar())
     15       if(ch=='-')
     16         f=-1;
     17     for(;ch>='0'&&ch<='9';ch=getchar())
     18       x=x*10+ch-'0';
     19     return x*f;
     20 }
     21 struct data
     22 {
     23     priority_queue<int> A,B;
     24     void push(int x)
     25       {
     26           A.push(x);
     27       }
     28     void shan(int x)
     29       {
     30           B.push(x);
     31       }
     32     void pop()
     33       {
     34         for(;B.size()&&A.top()==B.top();A.pop(),B.pop());
     35           if(A.size())
     36             A.pop();
     37       }
     38     int top()
     39       {
     40           for(;B.size()&&A.top()==B.top();A.pop(),B.pop());
     41           if(!A.size())
     42             return 0;
     43           return A.top();
     44       }
     45     int size()
     46       {
     47           return A.size()-B.size();
     48       }
     49     int stop()
     50       {
     51           if(size()<2)
     52             return 0;
     53           int x=top();
     54           pop();
     55           int y=top();
     56           push(x);
     57           return y;
     58       }
     59 }A,B[M],C[M];
     60 int bin[M],Log[2*M],cnt,next[2*M],head[M],u[2*M],n,st[2*M][22],deep[M],sum,size[M],f[M],G;
     61 bool yy[M];
     62 int fa[M],col[M],pos[M],T;
     63 void jia(int a1,int a2)
     64 {
     65     next[++cnt]=head[a1];
     66     head[a1]=cnt;
     67     u[cnt]=a2;
     68 }
     69 void dfs(int x,int F)
     70 {
     71     st[++T][0]=deep[x];
     72     pos[x]=T;
     73     for(int i=head[x];i;i=next[i])
     74       if(u[i]!=F)
     75         {
     76           deep[u[i]]=deep[x]+1;
     77             dfs(u[i],x);
     78             st[++T][0]=deep[x];
     79         }
     80 }
     81 void getroot(int x,int F)
     82 {
     83     size[x]=1;
     84     f[x]=0;
     85     for(int i=head[x];i;i=next[i])
     86       if(!yy[u[i]]&&u[i]!=F)
     87         {
     88             getroot(u[i],x);
     89             f[x]=max(f[x],size[u[i]]);
     90             size[x]+=size[u[i]];
     91         }
     92     f[x]=max(f[x],sum-size[x]);
     93     if(f[x]<f[G])
     94       G=x;
     95 }
     96 void fen(int x)
     97 {
     98     yy[x]=1;
     99     for(int i=head[x];i;i=next[i])
    100       if(!yy[u[i]])
    101         {
    102             G=0;
    103             sum=size[u[i]];
    104             getroot(u[i],x);
    105             fa[G]=x;
    106             fen(G);
    107         }
    108 }
    109 int stt(int x,int y)
    110 {
    111     int q=pos[x],w=pos[y];
    112     if(q>w)
    113       swap(q,w);
    114     int t=Log[w-q+1];
    115     return min(st[q][t],st[w-bin[t]+1][t]);
    116 }
    117 void kai(int x,int y)
    118 {
    119     if(x==y)
    120       {
    121           B[x].push(0);
    122           if(B[x].size()==2)
    123             A.push(B[x].top());
    124       }
    125     if(!fa[x])
    126       return;
    127     int f1=fa[x],D=deep[f1]+deep[y]-2*stt(f1,y),E=C[x].top();
    128     C[x].push(D);
    129     if(D>E)
    130       {
    131           int a1=B[f1].top()+B[f1].stop(),si=B[f1].size();
    132           if(E)
    133             B[f1].shan(E);
    134           B[f1].push(D);
    135           int a2=B[f1].top()+B[f1].stop();
    136           if(a2>a1)
    137             {
    138                 if(si>=2)
    139                   A.shan(a1);
    140                 if(B[f1].size()>=2)
    141                   A.push(a2);
    142           }
    143       }
    144     kai(f1,y);
    145 }
    146 void guan(int x,int y)
    147 {
    148     if(x==y)
    149       {
    150           if(B[x].size()==2)
    151             A.shan(B[x].top());
    152           B[x].shan(0);
    153       }
    154     if(!fa[x])
    155       return;
    156     int f1=fa[x],D=deep[f1]+deep[y]-2*stt(f1,y),E=C[x].top();
    157     C[x].shan(D);
    158     if(D==E)
    159       {
    160           int a1=B[f1].top()+B[f1].stop(),si=B[f1].size();
    161           B[f1].shan(D);
    162           if(C[x].top())
    163             B[f1].push(C[x].top());
    164           int a2=B[f1].top()+B[f1].stop();
    165           if(a2<a1)
    166             {
    167                 if(si>=2)
    168                   A.shan(a1);
    169                 if(B[f1].size()>=2)
    170                   A.push(a2);
    171           }
    172       }
    173     guan(f1,y);
    174 }
    175 int main()
    176 {
    177     n=read();
    178     for(int i=1;i<n;i++)
    179       {
    180           int a1=read(),a2=read();
    181           jia(a1,a2);
    182           jia(a2,a1);
    183       }
    184     bin[0]=1;
    185     for(int i=1;i<=20;i++)
    186       bin[i]=bin[i-1]*2;
    187     Log[0]=-1;
    188     for(int i=1;i<=200000;i++)
    189       Log[i]=Log[i/2]+1;
    190     dfs(1,0);
    191     for(int i=T;i;i--)
    192       for(int j=1;j<=19;j++)
    193         if(i+bin[j]-1<=T)
    194           st[i][j]=min(st[i][j-1],st[i+bin[j-1]][j-1]);
    195     f[0]=0x7fffffff;
    196     sum=n;
    197     getroot(1,0);
    198     fen(G);
    199     for(int i=1;i<=n;i++)
    200       col[i]=1;
    201     for(int i=1;i<=n;i++)
    202       C[i].push(0);
    203     for(int i=1;i<=n;i++)
    204        kai(i,i);
    205     char ch[10];
    206     int qqq=n;
    207     int m=read();
    208     for(;m;m--)
    209       {
    210           scanf("%s",ch);
    211           if(ch[0]=='G')
    212             {
    213                 if(qqq<=1)
    214                   printf("%d
    ",qqq-1);
    215                 else
    216                   printf("%d
    ",A.top());
    217           }
    218         else
    219           {
    220               int a1=read();
    221               if(col[a1])
    222                 {
    223                     qqq--;
    224                     guan(a1,a1);
    225                 }
    226             else
    227               {
    228                   qqq++;
    229                   kai(a1,a1);
    230               }
    231             col[a1]^=1;
    232           }
    233       }
    234     return 0;
    235 }
     
  • 相关阅读:
    2016 大连网赛
    LightOJ 1012 简单bfs,水
    Pyhton学习——Day30
    Client初见——python
    Server初见——python
    Pyhton学习——Day29
    Pyhton学习——Day28
    Pyhton学习——Day27
    Pyhton学习——Day26
    函数基础作业
  • 原文地址:https://www.cnblogs.com/xiw5/p/5611563.html
Copyright © 2020-2023  润新知