1 条题解

  • 0
    @ 2026-4-23 10:41:56

    在脑子里面想一下发现没有对应的模板,那么果断考虑上SG


    枚举每一个素数,然后模拟题意除掉这么一个过程。

    不过这么干就成了大模拟,显然(我也没试过,说不定可以)是不行的,然后选择的是形如pkp^k,那么就类似于一种状压(?)的感觉,把指数k作为函数下标。这样子就成了枚举消去素数的指数值。

    基于这样,我们又知道,指数值不可能很大,与数据有关联,所以预处理的时候把每个素数p能够使用的指数k记下来,减少了很多运算(由于不是很清楚实际大小就开成了map)。

    脑子里面胡一下就有后续状态

    now&((1<<i) - 1)|(now>>i)//now指当前状态,i指枚举到的k
    //顺便说当前k的下一个不是k ++ O.O
    

    然后:

    //这里是头文件,自己挂qwq
    int n, otp;//otp是输出
    map<int, int> mem, cors;//前面的记已有的SG值,后面那玩意是k
    
    //inline int counts(int now, int &goal){while (now)now >>=1, goal ++;}
    int Penu(int now){
    	if (!now || mem.find(now) != mem.end())return mem[now];
    	register int ans = 0;register set<int> mex;//不一定用set,随便来个啥都行,你甚至可以平板电视
    //	counts(now, counter);
    	for (register int i = 1;i < 31;i ++)if (now >> i)mex.insert(Penu(now&((1<<i) - 1)|(now>>i)));
    	while (mex.count(ans))ans ++;
    	return mem[now] = ans;
    }
    
    int main(){
    	mem[0] = 0;
    	scanf("%d", &n);
    	for (register int i = 1, j;i <= n;i ++){
    		scanf("%d", &j);//传说中的预处理
    		for (register int r = 2, c = 0;r*r <= j;r ++, c = 0){
    			while (!(j%r)){
    				c ++;
    				j /= r;
    			}
    			if (c)cors[r] |= (1<<c);//不要if也行
    		}
    		if (j > 1)cors[j] |= 2;//没除完就还来
    	}
    	for (map<int, int>::iterator cnt = cors.begin();cnt != cors.end();cnt ++)otp ^= Penu(cnt -> second);//指针日常操作,还可以用auto
    	return !printf("%s", otp?"Mojtaba":"Arpa");//Mojtaba先手
    }
    

    最后很想说一下做题感想,本来用的是平板电视,结果RE;递归改成map,RE;递归改成set,RE。最后发现主函数末尾写的是:

    return printf(....
    

    然后codeforces就一个劲的error 4,喜提了4次RE

    FF

    所以, 最开始先把 ! 打好再做题啊啊

    • 1

    信息

    ID
    4222
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    4
    已通过
    1
    上传者