• [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
    ",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);}
            }
        }
    }
  • 相关阅读:
    UVa 12716 GCD XOR (简单证明)
    2.12 运行计划并取得数据行
    nyoj 628 小媛在努力 【搜索】
    ArcGIS Server 10.2 公布Oracle11g数据源的 Feature Service
    项目复习期总结3:CSS引入方式,凝视,命名规范,背景,行高,文本属性
    Android使用有道翻译API实如今线翻译功能
    _00017 Kafka的体系结构介绍以及Kafka入门案例(0基础案例+Java API的使用)
    夜&#183; 启程
    你不知道的JavaScript(六)Box&Unbox
    pugixml读取unicode编码的xml文件的做法
  • 原文地址:https://www.cnblogs.com/coco-night/p/9691026.html
Copyright © 2020-2023  润新知