zoukankan      html  css  js  c++  java
  • 【Codeforces Round #432 (Div. 1) C】 Arpa and a game with Mojtaba

    【链接】h在这里写链接


    【题意】


    给你n个数,a1,a2,……,an,两人轮流从中改数,每次选一个素数p和一个正整数k,将a1到an中所有可以被p^k整除的数除p^k。当玩家在他的回合把所有数都变成1后,该玩家就赢了。

    【题解】


    每个素数的游戏都是独立的。
    比如2 3 4
    p=2的游戏和p=3的游戏。会发现是独立的。
    所以。把a[]里面的每个数字都分解一下质因数。
    如4 = 2^2
    则把dic[2] | = 1<<(2-1);
    表示有一个数字是2^2(也即记录a[]里面有数字是2^2的倍数);
    如9=3^2
    则dic[3] |= 1<<(2-1);
    表示有一个数字是3^2(也即记录a[]里面有数字是3^2的倍数);
    然后把所有的这些素数都分别求出sg函数,然后异或一下就好。
    对于某个素数p的游戏.
    每次枚举k从1..30,表示要除的p^k;
    显然,都除以p^k之后,p^i会变成p^(i-k);
    则除了p^1..p^(k-1)不变之外,dic[p]的其他的位全都会往前移动k位。
    则从状态x就转移成(x>>k) | ( ( 1<<( k-1 ) ) - 1);
    如果新的状态和旧的状态一样,则break;
    (sg[x] = mex(sg[i]),i是x能够通过一次转移到达的状态,知道这个就不难得到x的sg.);

    【错的次数】


    0

    【反思】


    每个素数构成了一个独立的游戏。
    知道这个,就不难写了。
    ->状态压缩.
    枚举每次的k,得到sg函数。

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e2;
    
    int n, a[N+10];
    map <int, int> dic;
    map <int, int> sg;
    
    int getsg(int x) {
        if (sg[x] != 0) {
            return sg[x];
        }
    
        map <int,int> flag;
        for (int k = 1; k <= 30; k++) {
            int temp = (x >> k);
            temp |= x&((1 << (k-1)) - 1);
            if (temp == x) break;
            flag[getsg(temp)] = 1;
        }
    
        int now = 0;
        while (flag[now] == 1) {
            now++;
        }
        return sg[x] = now;
    }
    
    int main() {
        //freopen("F:\rush.txt", "r", stdin);
        ios::sync_with_stdio(0),cin.tie(0);
        cin >> n;
        for (int i = 1; i <= n; i++) {
            int x,p;
            cin >> x;
            for (p = 2; p*p <= x; p++) {
                int cnt = 0;
                while (x%p == 0) {
                    x /= p;
                    cnt++;
                }
                if (cnt) dic[p] |= 1 << (cnt - 1);
            }
            if (x > 1) {
                dic[x] |= 1;
            }
        }
        
        int sum = 0;
        for (auto temp : dic) sum ^= getsg(temp.second);
        if (sum)
            puts("Mojtaba");
        else
            puts("Arpa");
        return 0;
    }


  • 相关阅读:
    MySQL 01-MySQL简介
    什么是数据库
    系统安装05-Xenserver 7.0安装
    系统安装04-VMware VCSA 6.5 系统安装
    poj--2516--Minimum Cost(最小费用流)
    hdoj--1533--Going Home(最小费用流)
    hdoj--5621--KK's Point(简单数学)
    hdoj--5620--KK's Steel(斐波那契数)
    nyoj--635--Oh, my goddess(dfs)
    poj--2236--棋盘问题(dfs)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626030.html
Copyright © 2011-2022 走看看