zoukankan      html  css  js  c++  java
  • BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)

    Description

    N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。

    Input

    第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。
    接下来M行,代表图中的每条边。
    接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。

    Output

     K行每行一个整数代表该组询问的联通块个数。

    Sample Input

    3 5 4 0
    1 3
    1 2
    2 1
    3 2
    2 2
    2 3
    1 5
    5 5
    1 2

    Sample Output

    2
    1
    3
    1

    解题思路:

    LCT维护连通图,维护最早被删除的边。

    像HH的项链那样搞就好了。

    只不过是主席树。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 const int N=1000000;
      5 class PST{
      6     #define lll tr[spc].ls
      7     #define rrr tr[spc].rs
      8     public:
      9         void update(int l,int r,int &spc,int lst,int pos,int v)
     10         {
     11             spc=++siz;
     12             tr[spc]=tr[lst];
     13             tr[spc].val+=v;
     14             if(l==r)
     15                 return ;
     16             int mid=(l+r)>>1;
     17             if(pos<=mid)
     18                 update(l,mid,tr[spc].ls,tr[lst].ls,pos,v);
     19             else
     20                 update(mid+1,r,tr[spc].rs,tr[lst].rs,pos,v);
     21             return ;
     22         }
     23         int query(int l,int r,int ll,int rr,int spc)
     24         {
     25             if(!spc)
     26                 return 0;
     27             if(l>rr||ll>r)
     28                 return 0;
     29             if(ll<=l&&r<=rr)
     30                 return tr[spc].val;
     31             int mid=(l+r)>>1;
     32             return query(l,mid,ll,rr,lll)+query(mid+1,r,ll,rr,rrr);
     33         }
     34         void fit(int array_size)
     35         {
     36             size=array_size;
     37             return ;
     38         }
     39         int Query(int l,int r)
     40         {
     41             int ans=0;
     42             ans=query(1,size,l,r,root[r]);
     43             return ans;
     44         }
     45         void ops(int pos)
     46         {
     47             root[pos]=root[pos-1];
     48             return ;
     49         }
     50         void Add(int i,int pos,int v)
     51         {
     52             update(1,size,root[i],root[i],pos,v);
     53             return ;
     54         }
     55     private:
     56         struct trnt{
     57             int ls;
     58             int rs;
     59             int val;
     60         }tr[N*10];
     61         int root[N];
     62         int siz;
     63         int size;
     64     #undef lll
     65     #undef rrr
     66 }P;
     67 class LCT{
     68     #define lll tr[spc].ch[0]
     69     #define rrr tr[spc].ch[1]
     70     #define ls ch[0]
     71     #define rs ch[1]
     72     public:
     73         bool whc(int spc)
     74         {
     75             return tr[tr[spc].fa].rs==spc;
     76         }
     77         void pushup(int spc)
     78         {
     79             tr[spc].mv=tr[spc].sl;
     80             if(lll)
     81                 tr[spc].mv=std::min(tr[spc].mv,tr[lll].mv);
     82             if(rrr)
     83                 tr[spc].mv=std::min(tr[spc].mv,tr[rrr].mv);
     84             return ;
     85         }
     86         void trr(int spc)
     87         {
     88             if(!spc)
     89                 return ;
     90             std::swap(lll,rrr);
     91             tr[spc].lzt^=1;
     92             return ;
     93         }
     94         void pushdown(int spc)
     95         {
     96             if(tr[spc].lzt)
     97             {
     98                 trr(lll);
     99                 trr(rrr);
    100                 tr[spc].lzt=0;
    101             }
    102             return ;
    103         }
    104         void recal(int spc)
    105         {
    106             if(!tr[spc].anc)
    107                 recal(tr[spc].fa);
    108             pushdown(spc);
    109             return ;
    110         }
    111         void rotate(int spc)
    112         {
    113             int f=tr[spc].fa;
    114             bool k=whc(spc);
    115             tr[f].ch[k]=tr[spc].ch[!k];
    116             tr[spc].ch[!k]=f;
    117             if(tr[f].anc)
    118             {
    119                 tr[f].anc=0;
    120                 tr[spc].anc=1;
    121             }else
    122                 tr[tr[f].fa].ch[whc(f)]=spc;
    123             tr[spc].fa=tr[f].fa;
    124             tr[f].fa=spc;
    125             tr[tr[f].ch[k]].fa=f;
    126             pushup(f);
    127             pushup(spc);
    128             return ;
    129         }
    130         void splay(int spc)
    131         {
    132             recal(spc);
    133             while(!tr[spc].anc)
    134             {
    135                 int f=tr[spc].fa;
    136                 if(tr[f].anc)
    137                 {
    138                     rotate(spc);
    139                     return ;
    140                 }
    141                 if(whc(spc)^whc(f))
    142                     rotate(spc);
    143                 else
    144                     rotate(f);
    145                 rotate(spc);
    146             }
    147             return ;
    148         }
    149         void access(int spc)
    150         {
    151             int lst=0;
    152             while(spc)
    153             {
    154                 splay(spc);
    155                 tr[rrr].anc=1;
    156                 tr[lst].anc=0;
    157                 rrr=lst;
    158                 pushup(spc);
    159                 lst=spc;
    160                 spc=tr[spc].fa;
    161             }
    162             return ;
    163         }
    164         void Mtr(int spc)
    165         {
    166             access(spc);
    167             splay(spc);
    168             trr(spc);
    169             return ;
    170         }
    171         void split(int x,int y)
    172         {
    173             Mtr(x);
    174             access(y);
    175             splay(y);
    176             return ;
    177         }
    178         void link(int x,int y)
    179         {
    180             Mtr(x);
    181             tr[x].fa=y;
    182             return ;
    183         }
    184         bool check(int x,int y)
    185         {
    186             Mtr(x);
    187             access(y);
    188             splay(y);
    189             pushdown(y);
    190             while(tr[y].ls)
    191             {
    192                 y=tr[y].ls;
    193                 pushdown(y);
    194             }
    195             return x==y;
    196         }
    197         int minplace(int x,int y)
    198         {
    199             split(x,y);
    200             return tr[y].mv;
    201         }
    202         void cut(int x,int y)
    203         {
    204             split(x,y);
    205             tr[y].ls=0;
    206             tr[x].fa=0;
    207             tr[x].anc=true;
    208             pushup(y);
    209             return ;
    210         }
    211         void fit(int size1,int size2)
    212         {
    213             siz=size1+size2;
    214             for(int i=1;i<=size1;i++)
    215                 tr[i].sl=0x3f3f3f3f;
    216             for(int i=1;i<=size2;i++)
    217                 tr[i+size1].sl=i;
    218             for(int i=1;i<=siz;i++)
    219             {
    220                 tr[i].anc=true;
    221                 pushup(i);
    222             }
    223             return ;
    224         }
    225     private:
    226         struct int_2{
    227             int v;
    228             int p;
    229         };
    230         struct trnt{
    231             int ch[2];
    232             int fa;
    233             int lzt;
    234             bool anc;
    235             int sl;
    236             int mv;
    237         }tr[N];
    238         int siz;
    239     #undef lll
    240     #undef rrr
    241     #undef ls
    242     #undef rs
    243 }T;
    244 int n,m,k,t;
    245 int lastans;
    246 int from[N];
    247 int plc[N];
    248 int to[N];
    249 int no[N];
    250 int main()
    251 {
    252     scanf("%d%d%d%d",&n,&m,&k,&t);
    253     for(int i=1;i<=m;i++)
    254     {
    255         scanf("%d%d",&from[i],&to[i]);
    256         no[i]=i;
    257         plc[i]=n+i;
    258     }
    259     T.fit(n,m);
    260     P.fit(m);
    261     for(int i=1;i<=m;i++)
    262     {
    263         P.ops(i);
    264         int a=from[i],b=to[i];
    265         if(a==b)
    266             continue;
    267         if(T.check(a,b))
    268         {
    269             int pos=T.minplace(a,b);
    270             P.Add(i,pos,-1);
    271             T.cut(plc[pos],from[pos]);
    272             T.cut(plc[pos],to[pos]);
    273         }
    274         T.link(plc[i],a);
    275         T.link(plc[i],b);
    276         P.Add(i,i,1);
    277     }
    278     while(k--)
    279     {
    280         int l,r;
    281         scanf("%d%d",&l,&r);
    282         if(t)
    283         {
    284             l^=lastans;
    285             r^=lastans;
    286         }
    287         lastans=n-P.Query(l,r);
    288         printf("%d
    ",lastans);
    289     }
    290     return 0;
    291 }
  • 相关阅读:
    linux时间格式化
    mysql5.7 安装版安装
    mac下面安装多个JDK
    linux一台机器文件传到另一台机器上
    取模运算
    【UVALive 7334】Kernel Knights
    【HDU 2604】Queuing
    【CodeForces 577B】Modulo Sum
    【CodeForces 504A】Misha and Forest
    【HDU 2203】亲和串
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10116611.html
Copyright © 2011-2022 走看看