BZOJ4589: Hard Nim

FWT模板题。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define MOD 1000000007
 5 #define rep(i,x,y) for(int i=(x);i<=(y);++i)
 6 #define drep(i,x,y) for(int i=(x);i>=(y);--i)
 7 inline int read(){
 8     char ch=getchar();int x=0,f=1;
 9     while(ch<'0'||ch>'9'){
10         if(ch=='-')f=-1;
11         ch=getchar();
12     }
13     while('0'<=ch&&ch<='9'){
14         x=x*10+ch-'0';
15         ch=getchar();
16     }
17     return x*f;
18 }
19 inline int Power(int x, int y) {
20     int ret = 1;
21     while(y) {
22         if(y & 1) ret = 1ll * ret * x % MOD;
23         x = 1ll * x * x % MOD; y >>= 1;
24     }
25     return ret;
26 }
27 inline void FWT_xor(int *a, int N, int op) {
28     int inv2 = (MOD + 1) / 2;
29     for(int d = 1; d < N; d <<= 1) {
30         for(int i = 0; i < N; i += (d << 1)) {
31             for(int j = 0; j < d; ++ j) {
32                 int X = a[i + j], Y = a[i + j + d];
33                 a[i + j] = (X + Y) % MOD;
34                 a[i + j + d] = (X + MOD - Y) % MOD;
35                 if(op == -1) {
36                     a[i + j] = 1ll * a[i + j] * inv2 % MOD;
37                     a[i + j + d] = 1ll * a[i + j + d] * inv2 % MOD;
38                 }
39             }
40         }
41     }
42 }
43 int a[200010];
44 int pri[200010], tot;
45 bool vis[200010];
46 inline void init() {
47     for(int i = 2; i <= 50000; ++ i) {
48         if(!vis[i]) {
49             pri[++ tot] = i;
50             for(int j = i + i; j <= 50000; j += i) {
51                 vis[j] = 1;
52             }
53         }
54     }
55 }
56 int main(){
57     int n, m;
58     init();
59     while(scanf("%d%d", &n, &m) != EOF) {
60         int N;
61         for(N = 1; N <= m; N <<= 1);
62         for(int i = 0; i < N; ++ i) a[i] = 0;
63         for(int i = 1; i <= tot; ++ i) {
64             if(pri[i] > m) break;
65             a[pri[i]] = 1;
66         }
67         FWT_xor(a, N, 1);
68         for(int i = 0; i < N; ++ i) {
69             a[i] = Power(a[i], n);
70         }
71         FWT_xor(a, N, -1);
72         printf("%d\n", a[0]);
73     }
74 }

 

posted @ 2019-06-30 23:03  iamunstoppable  阅读(241)  评论(0编辑  收藏  举报