• BZOJ3510首都(LCT)


    Description

    在X星球上有N个国家,每个国家占据着X星球的一座城市。由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的。
    X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失,而B国的国土也将归A国管辖。A国国王为了加强统治,会在A国和B国之间修建一条公路,即选择原A国的某个城市和B国某个城市,修建一条连接这两座城市的公路。
    同样为了便于统治自己的国家,国家的首都会选在某个使得其他城市到它距离之和最小的城市,这里的距离是指需要经过公路的条数,如果有多个这样的城市,编号最小的将成为首都。
    现在告诉你发生在X星球的战事,需要你处理一些关于国家首都的信息,具体地,有如下3种信息需要处理:
    1、A x y:表示某两个国家发生战乱,战胜国选择了x城市和y城市,在它们之间修建公路(保证其中城市一个在战胜国另一个在战败国)。
    2、Q x:询问当前编号为x的城市所在国家的首都。
    3、Xor:询问当前所有国家首都编号的异或和。

    Input

    第一行是整数N,M,表示城市数和需要处理的信息数。
    接下来每行是一个信息,格式如题目描述(A、Q、Xor中的某一种)。

    Output

    输出包含若干行,为处理Q和Xor信息的结果。

    Sample Input

    10 10
    Xor
    Q 1
    A 10 1
    A 1 4
    Q 4
    Q 10
    A 7 6
    Xor
    Q 7
    Xor

    Sample Output

    11
    1
    1
    1
    2
    6
    2

    解题思路:

    主要是动态维护重心。

    可以证明,新的中心在原来两个树中心路径上。

    那么就把这段路径提取出来找就好了。

    注意将重心旋转至根,保证时间复杂度。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll tr[spc].ch[0]
      5 #define rrr tr[spc].ch[1]
      6 #define ls ch[0]
      7 #define rs ch[1]
      8 struct trnt{
      9     int ch[2];
     10     int fa;
     11     int lzt;
     12     int wgt;
     13     int wgti;
     14     int ff;
     15     bool anc;
     16 }tr[1000000];
     17 int st[1000000];
     18 int tp;
     19 int n,m;
     20 int Xorsum;
     21 char cmd[10];
     22 bool whc(int spc)
     23 {
     24     return tr[tr[spc].fa].rs==spc;
     25 }
     26 int finf(int x)
     27 {
     28     return tr[x].ff==x?x:tr[x].ff=finf(tr[x].ff);
     29 }
     30 void pushup(int spc)
     31 {
     32     if(!spc)
     33         return ;
     34     tr[spc].wgt=tr[spc].wgti+tr[lll].wgt+tr[rrr].wgt+1;
     35     return ;
     36 }
     37 void trr(int spc)
     38 {
     39     if(!spc)
     40         return;
     41     std::swap(lll,rrr);
     42     tr[spc].lzt^=1;
     43     return ;
     44 }
     45 void pushdown(int spc)
     46 {
     47     if(tr[spc].lzt)
     48     {
     49         trr(lll);
     50         trr(rrr);
     51         tr[spc].lzt=0;
     52     }
     53     return ;
     54 }
     55 void recal(int spc)
     56 {
     57     if(!tr[spc].anc)
     58         recal(tr[spc].fa);
     59     pushdown(spc);
     60     return ;
     61 }
     62 void rotate(int spc)
     63 {
     64     int f=tr[spc].fa;
     65     bool k=whc(spc);
     66     tr[f].ch[k]=tr[spc].ch[!k];
     67     tr[spc].ch[!k]=f;
     68     if(tr[f].anc)
     69     {
     70         tr[spc].anc=1;
     71         tr[f].anc=0;
     72     }else
     73         tr[tr[f].fa].ch[whc(f)]=spc;
     74     tr[spc].fa=tr[f].fa;
     75     tr[f].fa=spc;
     76     tr[tr[f].ch[k]].fa=f;
     77     pushup(f);
     78     pushup(spc);
     79     return ;
     80 }
     81 void splay(int spc)
     82 {
     83     recal(spc);
     84     while(!tr[spc].anc)
     85     {
     86         int f=tr[spc].fa;
     87         if(tr[f].anc)
     88         {
     89             rotate(spc);
     90             break;
     91         }
     92         if(whc(spc)^whc(f))
     93             rotate(spc);
     94         else
     95             rotate(f);
     96         rotate(spc);
     97     }
     98     return ;
     99 }
    100 void access(int spc)
    101 {
    102     int lst=0;
    103     while(spc)
    104     {
    105         splay(spc);
    106         tr[spc].wgti+=tr[rrr].wgt;
    107         tr[spc].wgti-=tr[lst].wgt;
    108         tr[rrr].anc=1;
    109         tr[lst].anc=0;
    110         rrr=lst;
    111         pushup(spc);
    112         lst=spc;
    113         spc=tr[spc].fa;
    114     }
    115     return ;
    116 }
    117 void Mtr(int spc)
    118 {
    119     access(spc);
    120     splay(spc);
    121     trr(spc);
    122     return ;
    123 }
    124 void split(int x,int y)
    125 {
    126     Mtr(x);
    127     access(y);
    128     splay(y);
    129     return ;
    130 }
    131 void link(int x,int y)
    132 {
    133     split(x,y);
    134     tr[x].fa=y;
    135     tr[y].wgti+=tr[x].wgt;
    136     pushup(y);
    137     return ;
    138 }
    139 int Gravity(int spc)
    140 {
    141     int lwgt=0;
    142     int rwgt=0;
    143     int tot=tr[spc].wgt/2;
    144     int odd=tr[spc].wgt&1;
    145     int ans=0x3f3f3f3f;
    146     while(spc)
    147     {
    148         pushdown(spc);
    149         int ll,rr;
    150         ll=lwgt+tr[lll].wgt;
    151         rr=rwgt+tr[rrr].wgt;
    152         if(ll<=tot&&rr<=tot)
    153         {
    154             if(odd)
    155             {
    156                 ans=spc;
    157                 break;
    158             }
    159             if(ans>spc)
    160                 ans=spc;
    161         }
    162         if(ll>rr)
    163         {
    164             rwgt+=(tr[spc].wgti+tr[rrr].wgt+1);
    165             spc=lll;
    166         }else{
    167             lwgt+=(tr[spc].wgti+tr[lll].wgt+1);
    168             spc=rrr;
    169         }
    170     }
    171     splay(ans);
    172     return ans;
    173 }
    174 int main()
    175 {
    176     scanf("%d%d",&n,&m);
    177     for(int i=1;i<=n;i++)
    178     {
    179         tr[i].wgt=tr[i].anc=1;
    180         tr[i].ff=i;
    181         Xorsum^=i;
    182     }
    183     while(m--)
    184     {
    185         scanf("%s",cmd);
    186         if(cmd[0]=='A')
    187         {
    188             int x,y;
    189             scanf("%d%d",&x,&y);
    190             link(x,y);
    191             x=finf(x);
    192             y=finf(y);
    193             split(x,y);
    194             int g=Gravity(y);
    195             Xorsum=Xorsum^x^y^g;
    196             tr[x].ff=tr[y].ff=tr[g].ff=g;
    197         }
    198         if(cmd[0]=='Q')
    199         {
    200             int x;
    201             scanf("%d",&x);
    202             printf("%d
    ",finf(x));
    203         }
    204         if(cmd[0]=='X')
    205         {
    206             printf("%d
    ",Xorsum);
    207         }
    208     }
    209     return 0;
    210 }
  • 相关阅读:
    CPU飙高,OOM排查?
    反射
    Mybatits
    spring 基础问题
    java中格式化数字0和#区别
    java中File对象的mkdir和mkdirs的区别
    java截取字符串几种方式
    java工厂模式
    Java获取文件路径的几种方式
    jxl生成excel时,增加批注和冻结窗口
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9640015.html
Copyright © 2020-2023  润新知