zoukankan      html  css  js  c++  java
  • BZOJ1095: [ZJOI2007]Hide 捉迷藏(动态点分治)

    Description

      捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子。某天,Jiajia、Wind和孩子们决定在家里玩
    捉迷藏游戏。他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N-1条走廊的分布使得任意两个屋
    子都互相可达。游戏是这样进行的,孩子们负责躲藏,Jiajia负责找,而Wind负责操纵这N个屋子的灯。在起初的
    时候,所有的灯都没有被打开。每一次,孩子们只会躲藏在没有开灯的房间中,但是为了增加刺激性,孩子们会要
    求打开某个房间的电灯或者关闭某个房间的电灯。为了评估某一次游戏的复杂性,Jiajia希望知道可能的最远的两
    个孩子的距离(即最远的两个关灯房间的距离)。 我们将以如下形式定义每一种操作: C(hange) i 改变第i个房
    间的照明状态,若原来打开,则关闭;若原来关闭,则打开。 G(ame) 开始一次游戏,查询最远的两个关灯房间的
    距离。

    Input

      第一行包含一个整数N,表示房间的个数,房间将被编号为1,2,3…N的整数。接下来N-1行每行两个整数a, b,
    表示房间a与房间b之间有一条走廊相连。接下来一行包含一个整数Q,表示操作次数。接着Q行,每行一个操作,如
    上文所示。

    Output

      对于每一个操作Game,输出一个非负整数到hide.out,表示最远的两个关灯房间的距离。若只有一个房间是关
    着灯的,输出0;若所有房间的灯都开着,输出-1。

    Sample Input

    8
    1 2
    2 3
    3 4
    3 5
    3 6
    6 7
    6 8
    7
    G
    C 1
    G
    C 2
    G
    C 1
    G

    Sample Output

    4
    3
    3
    4

    解题思路:

    可以将开灯的点都压缩一下,那么这道题就变成了动态求一颗树的直径。

    静态的直径可以由一个点子树中不重复的最大值和次大值来更新。

    那么可以考虑更新一个点后重新实现Dfs回溯过程,这时候,我们就需要用一个堆来记录这个点的最长链。

    那样问题就变成了枚举两个儿子更新答案。

    实际上这是不需要的,在每个点再开一个堆记录答案就好了。

    最后将每个点的答案记录到的答案推入答案堆中。

    这个复杂度还是不能承受。

    将树重构形成点分树,每次都在树中暴力更新答案(注意距离要重新到原树中计算)。

    代码:(不想写带删除优先队列,就写了个Treap好慢啊QAQ)

      1 #include<ctime>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 typedef long long lnt;
      6 const int N=100010;
      7 struct pnt{
      8     int f;
      9     int fa;
     10     int hd;
     11     int dp;
     12     int tp;
     13     int dis;
     14     int wgt;
     15     int val;
     16     int mxs;
     17     int dcrt;
     18     int cnrt;
     19     bool vis;
     20 }p[N];
     21 struct trnt{
     22     int ls;
     23     int rs;
     24     int val;
     25     int num;
     26     int wgt;
     27     int rnd;
     28 }tr[N*80],strn;
     29 struct ent{
     30     int twd;
     31     int lst;
     32 }e[N<<1];
     33 int n,m;
     34 int cnt;
     35 int dfn;
     36 int siz;
     37 int top;
     38 int del;
     39 int bnum;
     40 int root;
     41 int size;
     42 int maxsize;
     43 int ansroot;
     44 int sta[N];
     45 int bin[N*80];
     46 char cmd[1000];
     47 void pushup(int rt)
     48 {
     49     if(!rt)
     50         return ;
     51     tr[rt].wgt=tr[tr[rt].ls].wgt+tr[tr[rt].rs].wgt+tr[rt].num;
     52     return ;
     53 }
     54 void lturn(int &rt)
     55 {
     56     int ll=tr[rt].ls;
     57     tr[rt].ls=tr[ll].rs;
     58     tr[ll].rs=rt;
     59     pushup(rt);
     60     rt=ll;
     61     pushup(rt);
     62     return ;
     63 }
     64 void rturn(int &rt)
     65 {
     66     int rr=tr[rt].rs;
     67     tr[rt].rs=tr[rr].ls;
     68     tr[rr].ls=rt;
     69     pushup(rt);
     70     rt=rr;
     71     pushup(rt);
     72     return ;
     73 }
     74 int newp(void)
     75 {
     76     if(bnum)
     77         return bin[bnum--];
     78     return ++siz;
     79 }
     80 void apply(int &rt)
     81 {
     82     rt=newp();
     83     tr[rt]=strn;
     84     tr[rt].num=1;
     85     tr[rt].rnd=rand();
     86     return ;
     87 }
     88 void Del(int rt)
     89 {
     90     bin[++bnum]=rt;
     91     return ;
     92 }
     93 void Insert(int &rt,int v)
     94 {
     95     if(!rt)
     96     {
     97         apply(rt);
     98         tr[rt].val=v;
     99         pushup(rt);
    100         return ;
    101     }
    102     if(tr[rt].val==v)
    103         tr[rt].num++;
    104     else if(tr[rt].val>v)
    105     {
    106         Insert(tr[rt].ls,v);
    107         if(tr[rt].rnd>tr[tr[rt].ls].rnd)
    108             lturn(rt);
    109     }else{
    110         Insert(tr[rt].rs,v);
    111         if(tr[rt].rnd>tr[tr[rt].rs].rnd)
    112             rturn(rt);
    113     }
    114     pushup(rt);
    115     return ;
    116 }
    117 void Delete(int &rt,int v)
    118 {
    119     if(!rt)
    120         return ;
    121     if(tr[rt].val==v)
    122     {
    123         if(tr[rt].num<=1)
    124         {
    125             if(!tr[rt].ls||!tr[rt].rs)
    126             {
    127                 Del(rt);
    128                 rt=tr[rt].ls+tr[rt].rs;
    129                 return ;
    130             }else{
    131                 if(tr[tr[rt].ls].rnd<tr[tr[rt].rs].rnd)
    132                 {
    133                     lturn(rt);
    134                     Delete(tr[rt].rs,v);
    135                 }else{
    136                     rturn(rt);
    137                     Delete(tr[rt].ls,v);
    138                 }
    139             }
    140         }else
    141             tr[rt].num--;
    142     }else if(tr[rt].val>v)
    143         Delete(tr[rt].ls,v);
    144     else
    145         Delete(tr[rt].rs,v);
    146     pushup(rt);
    147     return ;
    148 }
    149 int kth(int rt,int k)
    150 {
    151     if(tr[tr[rt].ls].wgt>=k)
    152         return kth(tr[rt].ls,k);
    153     if(tr[tr[rt].ls].wgt+tr[rt].num>=k)
    154         return tr[rt].val;
    155     return kth(tr[rt].rs,k-tr[tr[rt].ls].wgt-tr[rt].num);
    156 }
    157 int Maxval(int rt)
    158 {
    159     if(tr[rt].wgt==0)
    160         return -0x3f3f3f3f;
    161     return kth(rt,tr[rt].wgt);
    162 }
    163 int Secval(int rt)
    164 {
    165     if(tr[rt].wgt<=1)
    166         return -0x3f3f3f3f;
    167     return kth(rt,tr[rt].wgt-1);
    168 }
    169 int Chain(int rt)
    170 {
    171     if(tr[rt].wgt<2)
    172         return 0;
    173     return std::max(0,Maxval(rt)+Secval(rt));
    174 }
    175 void ade(int f,int t)
    176 {
    177     cnt++;
    178     e[cnt].twd=t;
    179     e[cnt].lst=p[f].hd;
    180     p[f].hd=cnt;
    181     return ;
    182 }
    183 void Basic_dfs(int x,int f)
    184 {
    185     p[x].wgt=1;
    186     p[x].f=f;
    187     p[x].dp=p[f].dp+1;
    188     int maxs=-1;
    189     for(int i=p[x].hd;i;i=e[i].lst)
    190     {
    191         int to=e[i].twd;
    192         if(to==f)
    193             continue;
    194         p[to].dis=p[x].dis+1;
    195         Basic_dfs(to,x);
    196         p[x].wgt+=p[to].wgt;
    197         if(maxs<p[to].wgt)
    198         {
    199             maxs=p[to].wgt;
    200             p[x].mxs=to;
    201         }
    202     }
    203     return ;
    204 }
    205 void Build_dfs(int x,int top)
    206 {
    207     if(!x)
    208         return ;
    209     p[x].tp=top;
    210     Build_dfs(p[x].mxs,top);
    211     for(int i=p[x].hd;i;i=e[i].lst)
    212     {
    213         int to=e[i].twd;
    214         if(to==p[x].f||to==p[x].mxs)
    215             continue;
    216         Build_dfs(to,to);
    217     }
    218     return ;
    219 }
    220 int Lca(int x,int y)
    221 {
    222     while(p[x].tp!=p[y].tp)
    223     {
    224         if(p[p[x].tp].dp<p[p[y].tp].dp)
    225             std::swap(x,y);
    226         x=p[p[x].tp].f;
    227     }
    228     if(p[x].dp>p[y].dp)
    229         std::swap(x,y);
    230     return x;
    231 }
    232 int Dis(int x,int y)
    233 {
    234     int z=Lca(x,y);
    235     return p[x].dis+p[y].dis-2*p[z].dis;
    236 }
    237 void grc_dfs(int x,int f)
    238 {
    239     sta[++top]=x;
    240     p[x].wgt=1;
    241     int maxs=-1;
    242     for(int i=p[x].hd;i;i=e[i].lst)
    243     {
    244         int to=e[i].twd;
    245         if(to==f||p[to].vis)
    246             continue;
    247         grc_dfs(to,x);
    248         p[x].wgt+=p[to].wgt;
    249         if(maxs<p[to].wgt)
    250             maxs=p[to].wgt;
    251     }
    252     maxs=std::max(maxs,size-p[x].wgt);
    253     if(maxs<maxsize)
    254     {
    255         root=x;
    256         maxsize=maxs;
    257     }
    258     return ;
    259 }
    260 void bin_dfs(int x,int f)
    261 {
    262     p[x].fa=f;
    263     p[x].vis=true;
    264     int tmp=size;
    265     if(f)
    266         for(int i=1;i<=top;i++)
    267             Insert(p[x].cnrt,Dis(f,sta[i]));
    268     Insert(p[x].dcrt,0);
    269     for(int i=p[x].hd;i;i=e[i].lst)
    270     {
    271         int to=e[i].twd;
    272         if(p[to].vis)
    273             continue;
    274         root=0;
    275         top=0;
    276         if(p[to].wgt<p[x].wgt)
    277             size=p[to].wgt;
    278         else
    279             size=tmp-p[x].wgt;
    280         maxsize=0x3f3f3f3f;
    281         grc_dfs(to,to);
    282         int rt=root;
    283         bin_dfs(root,x);
    284         Insert(p[x].dcrt,Maxval(p[rt].cnrt));
    285     }
    286     Insert(ansroot,Chain(p[x].dcrt));
    287     return ;
    288 }
    289 void Update(int oldans,int newans)
    290 {
    291     if(oldans==newans)
    292         return ;
    293     Delete(ansroot,oldans);
    294     Insert(ansroot,newans);
    295     return ;
    296 }
    297 void Insert(int x)
    298 {
    299     int la,na,lc,nc;
    300     la=Chain(p[x].dcrt);
    301     Insert(p[x].dcrt,0);
    302     na=Chain(p[x].dcrt);
    303     Update(la,na);
    304     for(int i=x;p[i].fa;i=p[i].fa)
    305     {
    306         lc=Maxval(p[i].cnrt);
    307         Insert(p[i].cnrt,Dis(x,p[i].fa));
    308         nc=Maxval(p[i].cnrt);
    309         if(lc==nc)
    310             continue;
    311         la=Chain(p[p[i].fa].dcrt);
    312         if(lc!=-0x3f3f3f3f)
    313             Delete(p[p[i].fa].dcrt,lc);
    314         Insert(p[p[i].fa].dcrt,nc);
    315         na=Chain(p[p[i].fa].dcrt);
    316         Update(la,na);
    317     }
    318     return ;
    319 }
    320 void Delete(int x)
    321 {
    322     int la,na,lc,nc;
    323     la=Chain(p[x].dcrt);
    324     Delete(p[x].dcrt,0);
    325     na=Chain(p[x].dcrt);
    326     Update(la,na);
    327     for(int i=x;p[i].fa;i=p[i].fa)
    328     {
    329         lc=Maxval(p[i].cnrt);
    330         Delete(p[i].cnrt,Dis(x,p[i].fa));
    331         nc=Maxval(p[i].cnrt);
    332         if(lc==nc)
    333             continue;
    334         la=Chain(p[p[i].fa].dcrt);
    335         Delete(p[p[i].fa].dcrt,lc);
    336         if(nc!=-0x3f3f3f3f)
    337             Insert(p[p[i].fa].dcrt,nc);
    338         na=Chain(p[p[i].fa].dcrt);
    339         Update(la,na);
    340     }
    341     return ;
    342 }
    343 int main()
    344 {
    345     scanf("%d",&n);
    346     for(int i=1;i<n;i++)
    347     {
    348         int a,b;
    349         scanf("%d%d",&a,&b);
    350         ade(a,b);
    351         ade(b,a);
    352     }
    353     Basic_dfs(1,1);
    354     Build_dfs(1,1);
    355     root=0;
    356     size=n;
    357     maxsize=0x3f3f3f3f;
    358     grc_dfs(1,1);
    359     bin_dfs(root,0);
    360     scanf("%d",&m);
    361     while(m--)
    362     {
    363         scanf("%s",cmd+1);
    364         if(cmd[1]=='G')
    365         {
    366             if(del==n)
    367                 puts("-1");
    368             else if(del==n-1)
    369                 puts("0");
    370             else
    371                 printf("%d
    ",Maxval(ansroot));
    372         }else{
    373             int x;
    374             scanf("%d",&x);
    375             p[x].val^=1;
    376             if(p[x].val)
    377             {
    378                 Delete(x);
    379                 del++;
    380             }else{
    381                 Insert(x);
    382                 del--;
    383             }
    384         }
    385     }
    386     return 0;
    387 }
  • 相关阅读:
    适配器模式(2)
    设计模式之6大设计原则(1)
    Mybatis框架基础支持层——反射工具箱之MetaClass(7)
    Mybatis框架基础支持层——反射工具箱之实体属性Property工具集(6)
    Mybatis框架基础支持层——反射工具箱之对象工厂ObjectFactory&DefaultObjectFactory(5)
    Mybatis框架基础支持层——反射工具箱之泛型解析工具TypeParameterResolver(4)
    Guava动态调用方法
    数据库的数据同步
    springboot(二十二)-sharding-jdbc-读写分离
    springboot(二十一)-集成memcached
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10160029.html
Copyright © 2011-2022 走看看