zoukankan      html  css  js  c++  java
  • USTC 1130 New Game

    USTC_1130

        时隔多日,回过头在再做这个题目时终于AC了,于是顿时觉得能力的提升确实需要时间的积淀。

        首先,如果Alice会输,那么各个棋子所在位置的sg函数值的异或必然为0,于是我们可以先预处理出各个节点的sg函数值。

        至于求方案,一开始的想法就是去dp了,比如用f[i][j][k]表示到第i个节点时放了j个棋子,且它们异或值为k的方案总数。这样i的上限是100,j是10000,k是128,这样的复杂度显然是不能承受的。

        我们联想到异或的性质,偶数个同一个数的异或为0,因此,整个局面的sg函数值,实际上只与每个节点上棋子数目的奇偶性有关,而剩下的棋子则两个两个的看成一组,放在哪里就无所谓了,可以用组合数算出方案数的。

        于是我们只要用f[i][j][k]表示到第i个节点时奇数个棋子的节点数为j,它们的异或值为k的的方案总数。这样j的上限就是100了。之后对于每个f[N][j][0],如果S-j是偶数,就用组合数算一下剩下的棋子摆放的方案数,再和f[N][j][0]乘起来之后,加到最终结果里即可。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 110
    #define MAXM 10010
    #define MOD 1000000007
    int N, M, S, U, V, e, first[MAXD], next[MAXM], v[MAXM], ny[MAXD], sg[MAXD], ch[MAXD][MAXD], f[MAXD][MAXD][130];
    void exgcd(long long a, long long b, long long &x, long long &y)
    {
        if(b == 0)
            x = 1, y = 0;
        else
            exgcd(b, a % b, y, x), y -= x * (a / b);
    }
    void prepare()
    {
        int i;
        long long x, y;
        for(i = 1; i <= 100; i ++)
        {
            exgcd(i, MOD, x, y);
            x = (x % MOD + MOD) % MOD;
            ny[i] = x;
        }
    }
    long long comb(int n, int m)
    {
        int i;
        long long ans = 1;
        for(i = n - m + 1; i <= n; i ++)
            ans = ans * i % MOD;
        for(i = 2; i <= m; i ++)
            ans = ans * ny[i] % MOD;
        return ans;
    }
    void add(int x, int y)
    {
        v[e] = y;
        next[e] = first[x], first[x] = e ++;
    }
    void init()
    {
        int i, x, y;
        scanf("%d%d%d", &N, &M, &S);
        e = 0;
        memset(first, -1, sizeof(first));
        for(i = 0; i < M; i ++)
        {
            scanf("%d%d", &x, &y);
            ++ x, ++ y;
            add(x, y);
        }
    }
    void dfs(int cur)
    {
        int i;
        memset(ch[cur], 0, sizeof(ch[cur]));
        for(i = first[cur]; i != -1; i = next[i])
        {
            if(sg[v[i]] == -1)
                dfs(v[i]);
            ch[cur][sg[v[i]]] = 1;
        }
        for(i = 0; ch[cur][i]; i ++);
        sg[cur] = i;
    }
    void solve()
    {
        int i, j, k;
        long long ans = 0;
        memset(sg, -1, sizeof(sg));
        for(i = 1; i <= N; i ++)
            if(sg[i] == -1)
                dfs(i);
        memset(f[0], 0, sizeof(f[0]));
        f[0][0][0] = 1;
        for(i = 1; i <= N; i ++)
            for(j = 0; j <= i; j ++)
                for(k = 0; k <= 128; k ++)
                    f[i][j][k] = (f[i - 1][j][k] + f[i - 1][j - 1][k ^ sg[i]]) % MOD;
        for(i = 0; i <= N; i ++)
            if((S - i) % 2 == 0)
                ans = (ans + f[N][i][0] * comb((S - i) / 2 + N - 1, N - 1)) % MOD;
        printf("%lld\n", ans);
    }
    int main()
    {
        int t;
        prepare();
        scanf("%d", &t);
        while(t --)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    CODING x 百果园 _ 水果零售龙头迈出 DevOps 体系建设第一步
    Nocalhost 亮相 CD Foundation 国内首届 Meetup,Keith Chan 将出席致辞
    做云原生时代标准化工具,实现高效云上研发工作流
    打造数字化软件工厂 —— 一站式 DevOps 平台全景解读
    WePack —— 助力企业渐进式 DevOps 转型
    CODING Compass —— 打造行云流水般的软件工厂
    Nocalhost —— 让云原生开发回归原始而又简单
    CODING 代码资产安全系列之 —— 构建全链路安全能力,守护代码资产安全
    Nocalhost:云原生开发新体验
    使用 Nocalhost 开发 Kubernetes 中的 APISIX Ingress Controller
  • 原文地址:https://www.cnblogs.com/staginner/p/2512451.html
Copyright © 2011-2022 走看看