• (2016北京集训十三)【xsy1533】mushroom


    题解:

    神题。。。我看到的时候直接吓懵了。。。

    这是一道STL题。。。否则可能要写可持久化ETT或者可持久化Toptree?

    用bitset来维护每个蘑菇上哪里有杂草,那么

    对于操作1和操作2:可以预处理每个点为跟的bitset;

    对于操作3和操作4:预处理两个点到根这条链上的bitset,先异或再或两个点的lca的bitset;

    对于操作5和操作6:直接暴力区间清零即可;

    询问直接贪心,由于随机所以复杂度O(玄学)(实际上应该是$O(frac{n}{32}+frac{n}{ln200})$?)

    用STL的bitset会T掉一个点。。。所以我只能看着dalao们的手写bitset瑟瑟发抖(然而也并没有完全看懂)

    代码:

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<queue>
      7 #include<map>
      8 #define inf 2147483647
      9 #define eps 1e-9
     10 using namespace std;
     11 typedef long long ll;
     12 typedef unsigned int uint;
     13 struct edge{
     14     int v,next;
     15 }a[100001];
     16 int n,m,u,v,op,L,now,cnt=1,tot=0,lg[65537],dep[50001],head[500001],rts[50001],fa[50001][17];
     17 uint *bt[100001],s1[50001][1601],s2[50001][1601];
     18 map<uint*,int>mp;
     19 void New(int k){
     20     bt[++cnt]=bt[k];
     21     mp[bt[cnt]]++;
     22 }
     23 void clr(int l,int r){
     24     if(r-l<40){
     25         for(int i=l;i<=r;i++){
     26             bt[now][i>>5]&=~((uint)1<<(i&31));
     27         }
     28         return;
     29     }
     30     int L=(l>>5)+1,R=(r>>5)-1;
     31     for(int i=L;i<=R;i++)bt[now][i]=0;
     32     for(int i=l;(i>>5)!=L;i++)bt[now][i>>5]&=~((uint)1<<(i&31));
     33     for(int i=r;(i>>5)!=R;i--)bt[now][i>>5]&=~((uint)1<<(i&31));
     34 }
     35 void rec(int k){
     36     if(mp[bt[k]]>1){
     37         uint *bb=bt[k];
     38         bt[k]=(uint*)malloc(L*sizeof(uint));
     39         mp[bt[k]]++;
     40         for(int i=0;i<L;i++)bt[k][i]=bb[i];
     41         mp[bt[k]]--;
     42     }
     43 }
     44 void Or(uint a[],uint b[]){for(int i=0;i<L;i++)a[i]|=b[i];}
     45 void And(uint a[],uint b[]){for(int i=0;i<L;i++)a[i]&=b[i];}
     46 void Nand(uint a[],uint b[]){for(int i=0;i<L;i++)a[i]&=~b[i];}
     47 void AND(uint a[],uint b[],uint c[],int k){
     48     uint t=a[k>>5]>>(k&31)&1;
     49     for(int i=0;i<L;i++)a[i]&=b[i]^c[i];
     50     a[k>>5]|=t<<(k&31);
     51 }
     52 void NAND(uint a[],uint b[],uint c[],int k){
     53     for(int i=0;i<L;i++)a[i]&=~(b[i]^c[i]);
     54     a[k>>5]&=~((uint)1<<(k&31));
     55 }
     56 void add(int u,int v){
     57     a[++tot].v=v;
     58     a[tot].next=head[u];
     59     head[u]=tot;
     60 }
     61 void dfs(int u,int ff,int dpt){
     62     dep[u]=dpt;
     63     fa[u][0]=ff;
     64     for(int i=1;i<=16;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
     65     for(int i=0;i<L;i++)s1[u][i]=s1[ff][i];
     66     s1[u][u>>5]^=(uint)1<<(u&31);
     67     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
     68         int v=a[tmp].v;
     69         if(v!=ff){
     70             dfs(v,u,dpt+1);
     71         }
     72     }
     73     s2[u][u>>5]^=(uint)1<<(u&31);
     74     for(int i=0;i<L;i++)s2[ff][i]|=s2[u][i];
     75 }
     76 int lca(int u,int v){
     77     if(dep[u]<dep[v])swap(u,v);
     78     int l=dep[u]-dep[v];
     79     for(int i=16;i>=0;i--){
     80         if((1<<i)&l)u=fa[u][i];
     81     }
     82     if(u==v)return u;
     83     for(int i=16;i>=0;i--){
     84         if(fa[u][i]!=fa[v][i]){
     85             u=fa[u][i],v=fa[v][i];
     86         }
     87     }
     88     return fa[u][0];
     89 }
     90 int query(int k){
     91     int ans=0;
     92     for(int i=1;i<=n;){
     93         if(bt[now][i>>5]>>(i&31)){
     94             uint t=(bt[now][i>>5]>>(i&(uint)31))<<(i&31),tt=t&-t;
     95             //printf("%lld %lld %lld
    ",(ll)bt[now][i>>5],(ll)t,(ll)tt);
     96             if(tt>65536)tt=lg[tt>>16]+16;
     97             else tt=lg[tt];
     98             ans++;
     99             i=((i&(~(uint)31))|tt)+k+1;
    100         }else i=((i>>5)+1)<<5;
    101     }
    102     return ans;
    103 }
    104 int main(){
    105     memset(head,-1,sizeof(head));
    106     scanf("%d",&n);
    107     for(int i=1;i<n;i++){
    108         scanf("%d%d",&u,&v);
    109         add(u,v);
    110         add(v,u);
    111     }
    112     L=(n+32)>>5;
    113     for(int i=0;i<=16;i++)lg[1<<i]=i;
    114     bt[0]=(uint*)malloc(L*sizeof(uint));
    115     bt[1]=(uint*)malloc(L*sizeof(uint));
    116     for(int i=0;i<L;i++)bt[0][i]=bt[1][i]=0;
    117     for(int i=1;i<=n;i++)bt[1][i>>5]|=(uint)1<<(i&31);
    118     dfs(1,0,1);
    119     scanf("%d",&m);
    120     for(int i=1;i<=m;i++){
    121         scanf("%d%d",&op,&now);
    122         switch(op){
    123             case 1:{New(now);break;}
    124             case 2:{
    125                 scanf("%d",&u);
    126                 rec(now);
    127                 Or(bt[now],bt[u]);
    128                 break;
    129             }
    130             case 3:{
    131                 scanf("%d",&u);
    132                 rec(now);
    133                 Nand(bt[now],s2[u]);
    134                 break;
    135             }
    136             case 4:{
    137                 scanf("%d",&u);
    138                 rec(now);
    139                 And(bt[now],s2[u]);
    140                 break;
    141             }
    142             case 5:{
    143                 scanf("%d%d",&u,&v);
    144                 rec(now);
    145                 NAND(bt[now],s1[u],s1[v],lca(u,v));
    146                 break;
    147             }
    148             case 6:{
    149                 scanf("%d%d",&u,&v);
    150                 rec(now);
    151                 AND(bt[now],s1[u],s1[v],lca(u,v));
    152                 break;
    153             }
    154             case 7:{
    155                 scanf("%d%d",&u,&v);
    156                 rec(now);
    157                 clr(u,v);
    158                 break;
    159             }
    160             case 8:{
    161                 scanf("%d%d",&u,&v);
    162                 rec(now);
    163                 clr(1,u-1),clr(v+1,n);
    164                 break;
    165             }
    166             case 9:{
    167                 scanf("%d",&u);
    168                 printf("%d
    ",query(u));
    169                 break;
    170             }
    171         }
    172     }
    173     return 0;
    174 }
  • 相关阅读:
    20170705总结
    20170703总结
    .NET 框架程序使用 Win32 API
    青春 就此别过
    Aptana Studio 2启动时提示 Workspace Cannot Be Created 解决办法
    App_GlobalResources.afvubzdv.resources.dll”--“拒绝访问。“
    c# 一维数组和二维数组的定义几种方式<转>.
    C#中Split分隔字符串的应用(C#、split、分隔、字符串)<转>
    C#操作字符串方法总结<转>
    C# 时间格式大全
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/9696671.html
Copyright © 2020-2023  润新知