首先对于m,求出它的原根g,则$$\prod_{i = 1} ^ {n} x_i = g^{\sum_{i = 1} ^ {n} ind[x_i]}$$
于是就变成加法的问题了,搞出母函数$f(x)$,于是变成$f(x)^{|n|}$的第m项是多少。。。
又注意到要模一个数。。。就只能NTT了QAQ
1 /************************************************************** 2 Problem: 3992 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:4064 ms 7 Memory:1260 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <bitset> 13 14 using namespace std; 15 typedef long long ll; 16 const int N = 16405; 17 const int G = 3; 18 const int mod = 1004535809; 19 20 int n, m, d, tar, S, g; 21 int ind[N]; 22 int w[2][N]; 23 int p[N], cnt_p; 24 bitset <N> is_p; 25 26 inline int read(); 27 28 ll pow(ll x, int y, int p) { 29 static ll res; 30 res = 1; 31 while (y) { 32 if (y & 1) res = res * x % p; 33 x = x * x % p, y >>= 1; 34 } 35 return res; 36 } 37 38 inline int get_inv(int x, int mod) { 39 return pow(x, mod - 2, mod); 40 } 41 42 inline void pre() { 43 int i, t; 44 w[0][0] = w[0][d] = 1; 45 t = pow(G, (mod - 1) / d, mod); 46 for (i = 1; i < d; ++i) w[0][i] = 1ll * w[0][i - 1] * t % mod; 47 for (i = 0; i <= d; ++i) w[1][i] = w[0][d - i]; 48 } 49 50 void NTT(int *x, int k, int v) { 51 int i, j, l, tmp; 52 for (i = j = 0; i < k; ++i) { 53 if (i > j) swap(x[i], x[j]); 54 for (l = k >> 1; (j ^= l) < l; l >>= 1); 55 } 56 for (i = 2; i <= k; i <<= 1) 57 for (j = 0; j < k; j += i) 58 for (l = 0; l < i >> 1; ++l) { 59 tmp = 1ll * x[j + l + (i >> 1)] * w[v][k / i * l] % mod; 60 x[j + l + (i >> 1)] = (1ll * x[j + l] - tmp + mod) % mod; 61 x[j + l] = (1ll * x[j + l] + tmp) % mod; 62 } 63 } 64 65 struct data { 66 int a[N]; 67 data() { 68 memset(a, 0, sizeof(a)); 69 } 70 71 inline void one() { 72 memset(a, 0, sizeof(a)); 73 a[0] = 1; 74 } 75 76 inline int& operator [] (int x) { 77 return a[x]; 78 } 79 80 inline data& operator *= (const data &t) { 81 static int b[N], i, inv; 82 memcpy(b, t.a, sizeof(b)); 83 NTT(a, d, 0), NTT(b, d, 0); 84 for (i = 0; i < d; ++i) a[i] = 1ll * a[i] * b[i] % mod; 85 NTT(a, d, 1); 86 for (i = m - 1; i <= m - 2 << 1; ++i) 87 (a[i - (m - 1)] += a[i]) %= mod, a[i] = 0; 88 for (inv = get_inv(d, mod), i = 0; i <= m - 2; ++i) 89 a[i] = 1ll * a[i] * inv % mod; 90 return *this; 91 } 92 93 friend inline data pow(data &x, int y) { 94 static data res; 95 res.one(); 96 while (y) { 97 if (y & 1) res *= x; 98 x *= x, y >>= 1; 99 } 100 return res; 101 } 102 } a; 103 104 inline void get_prime() { 105 is_p.set(); 106 int i, j, k; 107 for (i = 2; i < N; ++i) { 108 if (is_p[i]) p[++cnt_p] = i; 109 for (j = 1; j <= cnt_p; ++j) { 110 if ((k = i * p[j]) >= N) break; 111 is_p[k] = 0; 112 if (i % p[j] == 0) break; 113 } 114 } 115 } 116 117 int di[100], cnt_d; 118 inline void divide(int n) { 119 static int i, t; 120 for (cnt_d = 0, t = n, i = 1; p[i] * p[i] <= t; ++i) 121 if (t % p[i] == 0) { 122 di[++cnt_d] = p[i]; 123 while (t % p[i] == 0) t /= p[i]; 124 } 125 if (t > 1) di[++cnt_d] = t; 126 } 127 128 inline int get_g(int P) { 129 static int g, i, f; 130 divide(P - 1); 131 for (g = 2; g < P; ++g) { 132 for (i = f = 1; i <= cnt_d; ++i) 133 if (pow(g, (P - 1) / di[i], P) == 1) { 134 f = 0; 135 break; 136 } 137 if (f) return g; 138 } 139 } 140 141 int main() { 142 int i, x, now; 143 n = read(), m = read(), tar = read(), S = read(); 144 for (d = 1; d <= m << 1; d <<= 1); 145 pre(), get_prime(), g = get_g(m); 146 for (i = 0, now = 1; i < m - 1; ++i, now = now * g % m) 147 ind[now] = i; 148 for (i = 1; i <= S; ++i) { 149 if (x = read()) a[ind[x]] = 1; 150 } 151 printf("%d\n", pow(a, n)[ind[tar]]); 152 return 0; 153 } 154 155 inline int read() { 156 static int x; 157 static char ch; 158 x = 0, ch = getchar(); 159 while (ch < '0' || '9' < ch) 160 ch = getchar(); 161 while ('0' <= ch && ch <= '9') { 162 x = x * 10 + ch - '0'; 163 ch = getchar(); 164 } 165 return x; 166 }
(p.s. 1004535809这货的原根是3)
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen