zoukankan      html  css  js  c++  java
  • BZOJ1095 [ZJOI2007]Hide 捉迷藏

      动态树分治,用三个set分别维护每个重心到每一个子树的距离种类、每个重心所有子树的最大值和次大值、全局答案的最大值。复杂度O(nlogn^2)

      代码

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<vector>
      4 #include<set>
      5 #define pb push_back
      6 using namespace std;
      7 const int N = 501010;
      8 int size[N],flag[N],n,a,b,i,f[N],cnt,typ[N],deep[N];
      9 int jump[N][18];
     10 int q;
     11 char ch[5];
     12 vector<int> e[N];
     13 multiset<int> dist[N],ans[N],Ans;
     14 multiset<int>::iterator it;
     15 int getroot(int x,int fa,int n)
     16 {
     17     int i,tmp=0,rt=0;
     18     size[x]=1;
     19     for (i=0;i<e[x].size();i++)
     20     if ((e[x][i]!=fa)&&(!flag[e[x][i]]))
     21     {
     22         rt|=getroot(e[x][i],x,n);
     23         size[x]+=size[e[x][i]];
     24         if (size[e[x][i]]>n/2) tmp=1;
     25     }
     26     if (n-size[x]>n/2) tmp=1;
     27     if (tmp==1) return rt;else return x;
     28 }
     29 void gao(int x,int fa,int y,int dis)
     30 {
     31     dis++;
     32     int i;
     33     dist[y].insert(dis);
     34     for (i=0;i<e[x].size();i++)
     35     if ((!flag[e[x][i]])&&(e[x][i]!=fa))
     36     gao(e[x][i],x,y,dis);
     37 }
     38 void DFS(int x,int fa)
     39 {
     40     int i;
     41     deep[x]=deep[fa]+1;
     42     jump[x][0]=fa;
     43     for (i=1;i<=17;i++)
     44     jump[x][i]=jump[jump[x][i-1]][i-1];
     45     for (i=0;i<e[x].size();i++)
     46     if (e[x][i]!=fa) DFS(e[x][i],x);
     47 }
     48 int lca(int a,int b)
     49 {
     50     int i;
     51     if (deep[a]<deep[b]) a^=b^=a^=b;
     52     for (i=17;i>=0;i--)
     53     if (deep[jump[a][i]]>=deep[b]) a=jump[a][i];
     54     if (a==b) return a;
     55     for (i=17;i>=0;i--)
     56     if (jump[a][i]!=jump[b][i]) a=jump[a][i],b=jump[b][i];
     57     return jump[a][0];
     58 }
     59 int getdis(int x,int y)
     60 {
     61     int z=lca(x,y);
     62     return deep[x]+deep[y]-2*deep[z];
     63 }
     64 void del(int x)
     65 {
     66     int tmp=0;
     67     if (ans[x].size()>=2)
     68     {
     69         it=ans[x].end();
     70         --it;tmp+=*it;
     71         --it;tmp+=*it;
     72         it=Ans.lower_bound(tmp);
     73         Ans.erase(it); 
     74     }
     75 }
     76 void ins(int x)
     77 {
     78     int tmp=0;
     79     if (ans[x].size()>=2)
     80     {
     81         it=ans[x].end();
     82         --it;tmp+=*it;
     83         --it;tmp+=*it;
     84         Ans.insert(tmp); 
     85     }
     86 }
     87 void DEL(int y)
     88 {
     89     if (dist[y].size())
     90     {
     91         it=dist[y].end();--it;
     92         int tmp=*it;
     93         it=ans[f[y]].lower_bound(tmp);
     94         ans[f[y]].erase(it);
     95     }
     96 } 
     97 void INS(int y)
     98 {
     99     if (dist[y].size())
    100     {
    101         it=dist[y].end();--it;
    102         int tmp=*it;
    103         ans[f[y]].insert(tmp);
    104     }
    105 }
    106 int change(int x,int y)
    107 {
    108     del(x);
    109     if (typ[x]==1) 
    110     {
    111         it=ans[x].lower_bound(0);
    112         ans[x].erase(it);
    113     } 
    114     else
    115         ans[x].insert(0);
    116     while (x)
    117     {
    118         ins(x);
    119         if (f[x]) 
    120         { 
    121             del(f[x]);
    122             DEL(x);
    123             int dis=getdis(f[x],y);
    124             if (typ[y]==1)
    125             {
    126                 it=dist[x].lower_bound(dis);
    127                 dist[x].erase(it);
    128             }
    129             else
    130                 dist[x].insert(dis);
    131             INS(x);
    132         } 
    133         x=f[x];
    134     }
    135 }
    136 int dfs(int x,int n,int fa)
    137 {
    138     int i,y;
    139     x=getroot(x,0,n);
    140     f[x]=fa;
    141     flag[x]=1;
    142     ans[x].insert(0); 
    143     for (i=0;i<e[x].size();i++)
    144     if (!flag[e[x][i]])
    145     {
    146         if (size[e[x][i]]>size[x])
    147             y=dfs(e[x][i],n-size[x],x);
    148         else
    149             y=dfs(e[x][i],size[e[x][i]],x);
    150         gao(e[x][i],0,y,0);
    151         it=dist[y].end();
    152         ans[x].insert(*(--it));
    153     }
    154     ins(x);
    155     flag[x]=0;
    156     return x;
    157 }
    158 int main()
    159 {
    160     scanf("%d",&n);
    161     for (i=1;i<n;i++)
    162     {
    163         scanf("%d%d",&a,&b);
    164         e[a].pb(b);
    165         e[b].pb(a);
    166     }
    167     dfs(1,n,0);
    168     DFS(1,0);
    169     scanf("%d",&q);
    170     for (i=1;i<=q;i++)
    171     {
    172         scanf("%s",ch+1);
    173         if (ch[1]=='G')
    174         {
    175             if (cnt==n)
    176             printf("-1
    ");
    177             else
    178             if (cnt==n-1)
    179             printf("0
    ");
    180             else
    181             {
    182                 it=Ans.end();--it;
    183                 printf("%d
    ",*it);
    184             }
    185         }
    186         else
    187         if (ch[1]=='C')
    188         {
    189             scanf("%d",&a);
    190             if (typ[a]==0) 
    191             cnt++,typ[a]=1;
    192             else 
    193             cnt--,typ[a]=0;
    194             change(a,a);
    195         }
    196     }
    197 } 
  • 相关阅读:
    Lesson 九、Eclipse中打jar包并使用jar包
    Lesson 八、eclipse开发中常用的快捷键
    Lesson 七、关键字final和多态,抽象类和接口
    Lesson 六、Java中的继承
    Lesson 五、Java中代码块和静态代码块的用法
    Lesson 四、Java工具类帮助文档的制作和帮助文档的使用
    Lesson 三、匿名对象的理解和使用
    Lesson 二:java.util.Scanner的使用
    Lesson 一:Windows 常见DOS命令的使用以及Java语言的环境配置
    插件新增
  • 原文地址:https://www.cnblogs.com/fzmh/p/5724374.html
Copyright © 2011-2022 走看看