首先对于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 }
View Code

 (p.s. 1004535809这货的原根是3)

posted on 2015-04-23 21:46  Xs酱~  阅读(1090)  评论(0编辑  收藏  举报