2018秦皇岛ccpc-camp Steins;Gate (原根+FFT)

  1 //author Forsaken
  2 #define Hello the_cruel_world!
  3 #pragma GCC optimize(2)
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<cstdio>
  7 #include<string>
  8 #include<cstring>
  9 #include<vector>
 10 #include<map>
 11 #include<set>
 12 #include<queue>
 13 #include<stack>
 14 #include<utility>
 15 #include<cmath>
 16 #include<climits>
 17 #include<deque>
 18 #include<functional>
 19 #include<numeric>
 20 #define max(x,y) ((x) > (y) ? (x) : (y))
 21 #define min(x,y) ((x) < (y) ? (x) : (y))
 22 #define lowbit(x) ((x) & (-(x)))
 23 #define FRIN freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\1.in", "r", stdin)
 24 #define FROUT freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\1.out", "w", stdout)
 25 #define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
 26 #define outd(x) printf("%d\n", x)
 27 #define outld(x) printf("%lld\n", x)
 28 #define memset0(arr) memset(arr, 0, sizeof(arr))
 29 #define il inline
 30 using namespace std;
 31 typedef long long ll;
 32 typedef unsigned long long ull;
 33 typedef pair<int, int> pii;
 34 const int maxn = 6e5;
 35 const int INF = 0x7fffffff;
 36 const int mod = 1e9 + 7;
 37 const double eps = 1e-7;
 38 const double Pi = acos(-1.0);
 39 il int read_int() {
 40     char c;
 41     int ret = 0, sgn = 1;
 42     do { c = getchar(); } while ((c < '0' || c > '9') && c != '-');
 43     if (c == '-') sgn = -1; else ret = c - '0';
 44     while ((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0');
 45     return sgn * ret;
 46 }
 47 il ll read_ll() {
 48     char c;
 49     ll ret = 0, sgn = 1;
 50     do { c = getchar(); } while ((c < '0' || c > '9') && c != '-');
 51     if (c == '-') sgn = -1; else ret = c - '0';
 52     while ((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0');
 53     return sgn * ret;
 54 }
 55 il ll quick_pow(ll base, ll index, ll p) {
 56     ll res = 1;
 57     while (index) {
 58         if (index & 1)res = res * base % p;
 59         base = base * base % p;
 60         index >>= 1;
 61     }
 62     return res;
 63 }
 64 struct complex {
 65     complex operator + (const complex& rhs)const {
 66         return complex(x + rhs.x, y + rhs.y);
 67     }
 68     complex operator - (const complex& rhs)const {
 69         return complex(x - rhs.x, y - rhs.y);
 70     }
 71     complex operator * (const complex& rhs)const {
 72         return complex(x * rhs.x - y * rhs.y, x * rhs.y + y * rhs.x);
 73     }
 74     double x, y;
 75     complex(double _x = 0.0, double _y = 0.0) { x = _x, y = _y; }
 76 }a[maxn + 5], b[maxn + 5], res[maxn + 5];
 77 int r[maxn + 5], len = 1, p;
 78 void FFT(complex* arr, int type) {
 79     for (int i = 0; i < len; ++i)if (i < r[i])swap(arr[i], arr[r[i]]);
 80     for (int mid = 1; mid < len; mid <<= 1) {
 81         complex wn(cos(Pi / mid), type * sin(Pi / mid));
 82         for (int R = mid << 1, j = 0; j < len; j += R) {
 83             complex w(1, 0);
 84             for (int k = 0; k < mid; ++k, w = w * wn) {
 85                 complex x = arr[j + k], y = w * arr[j + mid + k];
 86                 arr[j + k] = x + y;
 87                 arr[j + mid + k] = x - y;
 88             }
 89         }
 90     }
 91 }
 92 bool is_prime[maxn + 5];
 93 int prime[maxn + 5], phi[maxn + 5], cnt;
 94 vector<int> factor;
 95 void init(int n) {
 96     for (int i = 2; i <= n; ++i)is_prime[i] = 1;
 97     phi[1] = 1;
 98     for (int i = 2; i <= n; ++i) {
 99         if (is_prime[i])prime[++cnt] = i, phi[i] = i - 1;
100         for (int j = 1; j <= cnt && i * prime[j] <= n; ++j) {
101             is_prime[i * prime[j]] = 0;
102             if (i % prime[j])phi[i * prime[j]] = phi[i] * phi[prime[j]];
103             else {
104                 phi[i * prime[j]] = phi[i] * prime[j];
105                 break;
106             }
107         }
108     }
109 }
110 bool check_is_root(int g, int n) {
111     if (quick_pow(g, phi[n], n) != 1)return 0;
112     for (int i = 0; i < factor.size(); ++i) {
113         int id = factor[i];
114         if (quick_pow(g, id, n) == 1)return 0;
115     }
116     return 1;
117 }
118 int find_root(int n) {
119     for (int i = 2; i * i <= phi[n]; ++i)
120         if (phi[n] % i == 0) {
121             if (i == phi[n] / i)factor.push_back(i);
122             else factor.push_back(i), factor.push_back(phi[n] / i);
123         }
124     int g = -1, value = 1;
125     for (g = 2; g <= 30; ++g)if (check_is_root(g, n))break;
126     return g;
127 }
128 int arr[maxn + 5], n, m, G, id[maxn + 5], rk[maxn + 5], sum[maxn + 5];
129 ll ans[maxn + 5], s[maxn + 5];
130 int len1, len2;
131 int main()
132 {
133     n = read_int(), m = read_int();
134     init(m);
135     G = find_root(m);
136     int u = 1;
137     for (int i = 0; i < m - 1; ++i) {
138         id[u] = i;
139         rk[i] = u;
140         u = 1ll * u * G % m;
141     }
142     for (int i = 1, v; i <= n; ++i) {
143         arr[i] = v = read_int();
144         v %= m;
145         if (v == 0) continue; 
146         ++sum[id[v]];
147     }
148     len1 = len2 = m;
149     for (int i = 0; i < m; ++i)a[i].x = b[i].x = sum[i];
150     while (len <= 2 * m)len *= 2, ++p;
151     for (int i = 0; i < len; ++i)r[i] = (r[i >> 1] >> 1) | ((i & 1) << (p - 1));
152     FFT(a, 1); FFT(b, 1);
153     for (int i = 0; i < len; ++i)res[i] = a[i] * b[i];
154     FFT(res, -1);
155     for (int i = 0; i < 2 * m; ++i)s[i] = (ll)(res[i].x / len + 0.5);
156     for (int i = 0; i < 2 * m; ++i) {
157         ll t = s[i];
158         ans[rk[i % (m - 1)]] += t;
159     }
160     ll tot = 1ll * n * n;       
161     for (int i = 1; i < m; ++i)tot -= ans[i];
162     ans[0] = tot;
163     for (int i = 1; i <= n; ++i) {
164         if (arr[i] >= m) outd(0);
165         else outld(ans[arr[i]]);
166     }
167     //system("pause");
168     return 0;
169 }
View Code

猜你喜欢

转载自www.cnblogs.com/Eterna-King/p/11210791.html
今日推荐