zoukankan      html  css  js  c++  java
  • UOJ266 【清华集训2016】Alice和Bob又在玩游戏

    Link
    Multi-SG模板题。
    (sg_u)(u)子树的SG函数值,(S_u)(u)到删除根节点的路径之后剩下的游戏的SG函数值的异或和。
    根节点的(S)就是它所有子树的SG函数值的疑惑和。
    在求出(S_u)之后,它的所有儿子(v)(S_v)需要异或上(S_uoplus sg_v)
    然后(sg_u=operatorname{mex}{S_v|vin son_u})
    那么使用Trie树维护一下就好了。

    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<cstring>
    namespace IO
    {
        char ibuf[(1<<21)+1],*iS,*iT;
        char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
        int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
    }
    using IO::read;
    const int N=100007,M=4000007;
    std::vector<int>e[N];
    int cnt,t,ch[M][2],tag[M],size[M],vis[N],sg[N],root[N];
    #define lc ch[x][0]
    #define rc ch[x][1]
    void pushup(int x){size[x]=size[lc]+size[rc];}
    void pushdown(int x,int d)
    {
        if(!tag[x]) return ;
        if(tag[x]>>d&1) std::swap(lc,rc);
        tag[lc]^=tag[x],tag[rc]^=tag[x],tag[x]=0;
    }
    void newnode(int&x){x=++cnt,tag[x]=lc=rc=0,size[x]=1;}
    int merge(int x,int y,int d)
    {
        if(!x||!y) return x+y;
        pushdown(x,d),pushdown(y,d),lc=merge(lc,ch[y][0],d-1),rc=merge(rc,ch[y][1],d-1);
        if(lc||rc) pushup(x);
        return x;
    }
    void insert(int&x,int v,int d)
    {
        if(!x) newnode(x);
        if(!~d) return ;
        pushdown(x,d),insert(ch[x][v>>d&1? 1:0],v,d-1),pushup(x);
    }
    int query(int x,int d)
    {
        if(!~d) return 0;
        pushdown(x,d);
        return size[lc]<1<<d? query(lc,d-1):query(rc,d-1)|1<<d;
    }
    void dfs(int u,int fa)
    {
        vis[u]=t;int s=0;
        for(std::vector<int>::iterator it=e[u].begin();it!=e[u].end();++it) if(*it^fa) dfs(*it,u),s^=sg[*it];
        for(std::vector<int>::iterator it=e[u].begin();it!=e[u].end();++it) if(*it^fa) tag[root[*it]]^=s^sg[*it],root[u]=merge(root[u],root[*it],16);
        insert(root[u],s,16),sg[u]=query(root[u],16);
    }
    void work()
    {
        int n=read(),m=read(),ans=0;
        ++t,memset(sg+1,0,n<<2),memset(root+1,0,n<<2);
        for(int i=1;i<=n;++i) e[i].clear();
        for(int i=1,u,v;i<=m;++i) u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
        for(int i=1;i<=n;++i) if(vis[i]^t) cnt=0,dfs(i,0),ans^=sg[i];
        puts(ans?"Alice":"Bob");
    }
    int main(){for(int t=read();t;--t)work();}
    
  • 相关阅读:
    【转】 UI自动化测试的关注点
    使用MapReduce将HDFS数据导入到HBase(一)
    Hadoop2.4.1 MapReduce通过Map端shuffle(Combiner)完成数据去重
    Hadoop2.4.1 使用MapReduce简单的数据清洗
    Hadoop2.4.1 64-Bit QJM HA and YARN HA + Zookeeper-3.4.6 + Hbase-0.98.8-hadoop2-bin HA Install
    hadoop2.2.0 MapReduce求和并排序
    hadoop2.2.0 MapReduce分区
    hadoop2.2.0伪分布模式64位安装
    hadoop2.2.0 MapReduce的序列化
    MyEclipse8.6下的svn插件安装
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12301037.html
Copyright © 2011-2022 走看看