[2016北京集训试题6]mushroom-[bitset]

Description

Solution

bitset是个好东西啊。。强行压位什么的真是够orz。

由于所有的蘑菇上房间的长相是一样的,我们针对每个房间,算出它到根节点的bitset和以它为根的子树的bitset。

每次新开一个蘑菇,为了防止被卡空间,我们只是把指针指向蘑菇u的bitset,并且cnt[u]++。只有当对这个新蘑菇进行操作的时候,才给它单独开一个 bitset。

本题的题解一句话-优雅的暴力。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
typedef unsigned int ui;
int n,q,T;
struct G{int y,nxt;}g[100010];int h[50010],tot=0;
int fa[50010][17],dep[50010];
 
ui up[50010][1610],down[50010][1610];
void dfs(int x,int f)
{
    fa[x][0]=f;dep[x]=dep[f]+1;
    for (int i=1;i<=16;i++)  fa[x][i]=fa[fa[x][i-1]][i-1];
    for (int i=0;i<T;i++) up[x][i]=up[f][i];
    up[x][x>>5]|=1u<<(x&31);
     
    for (int i=h[x];i;i=g[i].nxt) if (g[i].y!=f) dfs(g[i].y,x);
    down[x][x>>5]|=1u<<(x&31);
    for (int i=0;i<T;i++) down[f][i]|=down[x][i];
}
int lca(int x,int y)
{
    if (dep[x]<dep[y]) swap(x,y);
    for (int i=16;i>=0;i--) if (dep[fa[x][i]]>dep[y]) x=fa[x][i];
    if (dep[x]>dep[y]) x=fa[x][0];
    if (x==y) return x;
    for (int i=16;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}
int bin[100010];
ui *_bit[100010];int _new=1;
map<ui*,int>cnt;
void init_bit()
{
    ++cnt[_bit[1]=(ui*)malloc(T*sizeof(ui))];
    for (int i=0;i<T;i++) _bit[1][i]=0;
    for (int i=1;i<=n;i++) _bit[1][i>>5]|=1u<<(i&31);
}
void query(ui *b,int w)
{
    int cost=0;w++;
    for (int i=1;i<=n;)
    if (b[i>>5]>>(i&31))
    {
        ui re=b[i>>5]>>(i&31)<<(i&31),k=re&-re;
        if (k>65536) k=bin[k>>16]+16;else k=bin[k];
        cost++,i=(i&(~31u)|k)+w;
    } else i=(i>>5)+1<<5;
    printf("%d\n",cost);
}
void clear_bit(int u,int x,int y)
{
    if (y-x<=32) {for (int i=x;i<=y;i++) _bit[u][i>>5]&=~(1u<<(i&31));return;}
    int l=x>>5,r=y>>5;l++;r--;
    for (int i=l;i<=r;i++) _bit[u][i]=0;
    for (int i=x;i>>5<l;i++) _bit[u][i>>5]&=~(1u<<(i&31));
    for (int i=y;i>>5>r;i--) _bit[u][i>>5]&=~(1u<<(i&31)); 
}
int t,u,v,x,y,w;
int main()
{                                        
    scanf("%d",&n);T=(n+32)>>5;
    for (int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        g[++tot]=G{y,h[x]};h[x]=tot;
        g[++tot]=G{x,h[y]};h[y]=tot;
    }
    dfs(1,0);init_bit();
    for (int i=0;i<=16;i++) bin[1<<i]=i;
    scanf("%d",&q);
    while (q--)
    {
        scanf("%d",&t);scanf("%d",&u);
        if (t==1){ ++cnt[_bit[++_new]=_bit[u]];}
        else if (t==9){scanf("%d",&w);query(_bit[u],w);}
        else
        {
            if (cnt[_bit[u]]>1)
            {
                ui* c=_bit[u];
                cnt[c]--;
                _bit[u]=(ui*)malloc(T*sizeof(ui));
                for (int i=0;i<T;i++) _bit[u][i]=c[i];
                cnt[_bit[u]]++;
            }
            if (t==2)
            {
                scanf("%d",&v);
                for (int i=0;i<T;i++) _bit[u][i]|=_bit[v][i];                
            }
            if (t==3)
            {
                scanf("%d",&x);
                for (int i=0;i<T;i++) _bit[u][i]&=~down[x][i];               
            }
            if (t==4)
            {
                scanf("%d",&x);
                for (int i=0;i<T;i++) _bit[u][i]&=down[x][i];
            }
            if (t==5)
            {
                scanf("%d%d",&x,&y);
                int LCA=lca(x,y);
                for (int i=0;i<T;i++) _bit[u][i]&=~(up[x][i]^up[y][i]);
                _bit[u][LCA>>5]&=~(1u<<(LCA&31));   
            }
            if (t==6)
            {
                scanf("%d%d",&x,&y);
                int LCA=lca(x,y);
                ui c=_bit[u][LCA>>5]>>(LCA&31)&1;
                for (int i=0;i<T;i++) _bit[u][i]&=up[x][i]^up[y][i];
                _bit[u][LCA>>5]|=c<<(LCA&31);               
            }
            if (t==7){scanf("%d%d",&x,&y);clear_bit(u,x,y);}
            if (t==8){scanf("%d%d",&x,&y);clear_bit(u,1,x-1);clear_bit(u,y+1,n);}
        }
    }
}

 

posted @ 2018-09-22 20:06  _雨后阳光  阅读(130)  评论(0编辑  收藏  举报