zoukankan      html  css  js  c++  java
  • P3727 曼哈顿计划E

    点分治+SG函数还真是令人意外的组合啊

    思路

    这道题看到找一条满足条件的链,想到点分治

    看到博弈,想到SG函数

    然后就变成一道SG函数+点分治的题了

    然后1e9的SG函数怎么搞?当然是打表了

    然后各种出锅

    • 多组数据记得清零
    • SG函数不要打错表QwQ

    因为对着租酥雨julao的blog调了好久,所以代码极其相似

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <unordered_map>
    using namespace std;
    int T,n,s,k,fir[30100],nxt[30100<<1],u[30100<<1],v[30100<<1],cnt,root,sz[30100],f[30100],vis[30100],ass=0,Siz,w_p[30100],tp_val;
    unordered_map<int,int> S;
    void addedge(int ui,int vi){
        cnt++;
        u[cnt]=ui;
        v[cnt]=vi;
        nxt[cnt]=fir[ui];
        fir[ui]=cnt;
    }
    int SG3(int x){//k==3 时 , SG[x]=floor(x/k)
        return x/s;
    }
    int SG1(int x){//k==1 时 , SG[x]=x
        return x;
    }
    int SG2(int x){
        if((x+1)%(s+1)==0)
            return 2;
        else
            return x%2;
    }
    int SG4(int x){
        if(!x)
            return 0;
        if(x%4==1||x%4==2)
            return x;
        if(x%4==3)
            return x+1;
        else
            return x-1;
    }
    int SG(int x){
        if(k==1)
            return SG1(x);
        else if(k==2)
            return SG2(x);
        else if(k==3)
            return SG3(x);
        else if(k==4)
            return SG4(x);
        else    
            return 0;
    }
    void findroot(int u,int fa){
        sz[u]=f[u]=1;
        for(int i=fir[u];i;i=nxt[i]){
            if(vis[v[i]]||v[i]==fa)
                continue;
            findroot(v[i],u);
            sz[u]+=sz[v[i]];
            f[u]=max(f[u],sz[v[i]]);
        }
        f[u]=max(Siz-sz[u],f[u]);
        if(f[u]<f[root] || !root)
            root=u;
    }
    void queryhas(int u,int fa,int d){
        if(S[d^tp_val])
            ass=1;
        for(int i=fir[u];i;i=nxt[i]){
            if(v[i]==fa||vis[v[i]])
                continue;    
            queryhas(v[i],u,d^w_p[v[i]]);
        }
    }
    void getxor(int u,int fa,int d){
        S[d]++;
        for(int i=fir[u];i;i=nxt[i]){
            if(v[i]==fa||vis[v[i]])
                continue;    
            getxor(v[i],u,d^w_p[v[i]]);
        }
    }
    void divide(int u){
        vis[u]=true;
        S[0]++;
        tp_val=w_p[u];
        for(int i=fir[u];i;i=nxt[i]){
            if(vis[v[i]])
                continue;
            queryhas(v[i],0,w_p[v[i]]);
            getxor(v[i],0,w_p[v[i]]);
        }
        S.clear();
        for(int i=fir[u];i;i=nxt[i]){
            if(vis[v[i]])
                continue;
            Siz=sz[v[i]];
            root=0;
            findroot(v[i],0);
            divide(root);
        }
    }
    // void SG(int s){
    //     for(int i=1;i<=90;i++){
    //         memset(barrel,0,sizeof(barrel));
    //         for(int j=1;j<=i;j++){
    //             barrel[sg[i-j]]=true;
    //             }
    //         for(int j=1;j<i;j++){
    //             barrel[sg[j]^sg[i-j]]=true;
    //         }
    //         for(int j=0;j<=10000-1;j++)
    //             if(!barrel[j]){
    //                 sg[i]=j;
    //                 break;
    //             }
    //     }
    // }
    int main(){
        #ifndef ONLINE_JUDGE
            freopen("t.in","r",stdin);
        #endif
        scanf("%d",&T);
        while(T--){
            memset(fir,0,sizeof(fir));
            memset(nxt,0,sizeof(nxt));
            memset(vis,0,sizeof(vis));
            cnt=0;
            ass=0;
            S.clear();
            scanf("%d",&n);
            for(int i=1;i<=n-1;i++){
                int a,b;
                scanf("%d %d",&a,&b);
                addedge(a,b);
                addedge(b,a);
            }
            for(int i=1;i<=n;i++)
                scanf("%d",&w_p[i]);
            scanf("%d",&k);
            if(k==2||k==3)
                scanf("%d",&s);
            for(int i=1;i<=n;i++)
                w_p[i]=SG(w_p[i]);
            root=0;
            Siz=n;
            findroot(1,0);
            divide(root);
            if(ass)
                printf("Mutalisk ride face how to lose?
    ");
            else
                printf("The commentary cannot go on!
    ");
        }
        return 0;
    }
    
    
  • 相关阅读:
    mysql执行update报错 Err] 1055
    scp从远程指定目录拷贝文件到本地指定目录
    内存溢出
    BlockingQueue-----多线程(一)
    版主
    Mybatis学习总结-----mybatis中refid是什么意思(十)
    Mybatis学习总结--------Mybatis <where>标签 (九)
    @RequestMapping 和 @GetMapping @PostMapping 区别
    @RequiresPermissions ,@RequiresUser , @RequiresGuest ,@RequiresRoles 解释
    response.setHeader的各种用法 ------ 笔记(一)
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10104308.html
Copyright © 2011-2022 走看看