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 }
posted on 2019-07-18 23:46 Eterna_King 阅读(203) 评论(0) 编辑 收藏 举报