[CodeForces850C]Arpa and a game with Mojtaba

题目大意:
  给你一个包含n个数的数列,两个人轮流对数列进行如下操作:
  选择一个质数p和一个正整数k,将数列中所有能被p^k整除的数除以p^k。
  最后不能操作者负。
  问先手是否有必胜策略。

思路:
  显然,结果不直接与数列中数的值有关,而与数列中每个数的质因数及其次数有关,因此我们可以将每个质因数分开考虑。
  枚举数列中出现的每一个质因数p,对数列中的数除去p^k就相当于将p对应的次数减去k。
  如果不同的数对于同一个质因数p,对应的次数相同,那么无论除去p的几次,对于这两个数的影响都是一样的。
  那么我们只需要将不同的质数作为我们的子游戏,游戏状态记录p出现次数(即,如果一个数中包含17,一个数中包含17^2,那么就记录1和2)。
  极限情况,2^31>1e9,那么对于每一个质数,我们可以用一个int类型状压记录出现次数。
  即,若状态s的第i位为1,则p^i在数列中出现。
  求SG函数的时候,我们可以发现SG函数的取值仅与出现次数,即状态s有关,而与具体是哪个质数无关。
  我们可以从s的最高位枚举,依次考虑把s在i后面的位数减掉的情况,这样,较高的次数在降次以后会加到较低的位数,这一操作可以用位运算(x%si)|(x/si)表示。
  对于边界情况,s=1时,表示数列中已经没有这样的质因数,SG值显然是0。

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<vector>
 5 #include<cstring>
 6 #include<ext/hash_map>
 7 inline int getint() {
 8     register char ch;
 9     while(!isdigit(ch=getchar()));
10     register int x=ch^‘0‘;
11     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^‘0‘);
12     return x;
13 }
14 const int N=100;
15 __gnu_cxx::hash_map<int,int> sg;
16 int a[N];
17 inline int count(int &x,const int &p) {
18     int ret=0;
19     while(!(x%p)) {
20         ret++;
21         x/=p;
22     }
23     return ret;
24 }
25 int getsg(const int x) {
26     if(sg.count(x)) {
27         return sg[x];
28     }
29     if(x==1) return sg[x]=0;
30     int si=1<<30;
31     while(!(x&si)) si>>=1;
32     int mex[10000];
33     memset(mex,0,sizeof mex);
34     while(si!=1) {
35         mex[getsg((x%si)|(x/si))]=x;
36         si>>=1;
37     }
38     int tmp=0;
39     while(mex[tmp]==x) tmp++;
40     return sg[x]=tmp;
41 }
42 int main() {
43     int n=getint();
44     for(int i=0;i<n;i++) {
45         a[i]=getint();
46     }
47     int ans=0;
48     for(int i=0;i<n;i++) {
49         int tmp=a[i];
50         for(int j=2;j<=sqrt(tmp);j++) {
51             if(!(tmp%j)) {
52                 int s=0;
53                 for(int k=0;k<n;k++) {
54                     s|=1<<count(a[k],j);
55                 }
56                 ans^=getsg(s);
57             }
58         }
59         if(a[i]!=1) {
60             int p=a[i];
61             int s=0;
62             for(int k=0;k<n;k++) {
63                 s|=1<<count(a[k],p);
64             }
65             ans^=getsg(s);
66         }
67     }
68     puts(ans?"Mojtaba":"Arpa");
69     return 0;
70 }
时间: 2024-11-09 00:01:20

[CodeForces850C]Arpa and a game with Mojtaba的相关文章

Codeforces 850C E. Arpa and a game with Mojtaba

对每个数统计其素数因子各次方数的数,然后通过y = (x>>i) | (x&((1<<(i-1))-1)) 模拟delete x and add  to the list 操作,用grund函数将每个因子的情况映射为NIM问题中一个堆的情况,再按NIM问题的求解方法求解 参考链接 https://www.topcoder.com/community/data-science/data-science-tutorials/algorithm-games/ #include&l

[Codeforces 850C]Arpa and a game with Mojtaba

Description 题库链接 两个人 Van♂ 游戏.给出 \(n\) 个正整数 \(a_i\) .两人轮流操作,每次选出一个素数 \(p\) 和一个幂数 \(k\) ,选择的前提为该 \(n\) 个数中有 \(p^k\) 的倍数.接着将所有的 \(p^k\) 的倍数除以 \(p^k\) .变成新的序列,继续操作.不能操作者为败,问先手是否必胜. \(1\leq 100\leq n,1\leq a_i\leq 10^9\) Solution 首先显然的是不同的素数间是不会互相影响的.显然这个

arpa/inet.h所引起的Segmentation fault及网络编程常见的头文件

最近在学习Linux网络编程方面的知识,感觉还是有些困难.主要是对协议过程的理解,还有socket的API的理解不够深刻.今天复习编写了一个TCP的服务端和客户端的程序实现client.c从命令行参数中获得一个字符串发给服务器,然后接收服务器返回的已处理的字符串并打印. server.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h>

Arpa&#39;s weak amphitheater and Mehrdad&#39;s valuable Hoses CodeForces - 742D

Just to remind, girls in Arpa's land are really nice. Mehrdad wants to invite some Hoses to the palace for a dancing party. Each Hos has some weight wi and some beauty bi. Also each Hos may have some friends. Hoses are divided in some friendship grou

D. Arpa&#39;s weak amphitheater and Mehrdad&#39;s valuable Hoses 分组背包模板题

http://codeforces.com/problemset/problem/742/D 并查集预处理出所有关系. 一开始的时候,我预处理所有关系后,然后选择全部的时候,另起了一个for,然后再判断. 这样是不对的.因为这样使得同一组里面可能选择了两次. 3 0 2 1 2 3 1 1 3 #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include &

#383 Div1 Problem B Arpa&#39;s weak amphitheater.... (分组背包 &amp;&amp; 并查集)

题意 : 有n个人,每个人都有颜值bi与体重wi.剧场的容量为W.有m条关系,xi与yi表示xi和yi是好朋友,在一个小组. 每个小组要么全部参加舞会,要么参加人数不能超过1人. 问保证总重量不超过W,剧场中的颜值最大能到多少? 分析 : 很显然的分组背包题目, 不过有所不同, 先来回顾一下普通的分组背包的描述 给出一个背包,背包有容量C,再给出N组物品,每组物品有ki种,每种物品有对应的体积Vi,价值Pi,每组物品至多选一种,且最多取一件.求用背包装物品,能获得的最大总价值是多少.可以发现和上

cfodeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

题目链接:Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 第一次写\(dsu\ on\ tree\),来记录一下 \(dsu\ on\ tree\)主要维护子树信息,往往可以省掉一个数据结构的启发式合并.大体思路如下: 轻重链路径剖分之后,对每个点先递归处理他的所有轻儿子,每次处理完轻儿子之后把这棵子树的信息清空.最后再来处理重孩子,重儿子的信息就可以不用清空了.由于我们是用一个全局数组来记录信息的,重儿子子树的信息就仍然保留

ARPA

ARPA是英文Advanced Research Projects Agency的缩写,代表美国国防部高级研究计划署.是美国国防部高级研究计划管理局因军事目的而建立的,开始时只连接了4台主机,这便是只有四个网点的网络之父

http://codeforces.com/contest/741/problem/B B. Arpa&#39;s weak amphitheater and Mehrdad&#39;s valuable Hoses

题意: 给出上限体重W 然后还给出每个人的体重wi 和 魅力值 bi 互为伙伴的对(xi, yi) 可以凑成group 思路: 并查集找出所有的group 暴力背包 对于每一个group 要选出这一组内选一个人时的最优结果, 如果所有人的体重和小于等于W,还得考虑选所有人的情况 #include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #include &l