//**************************************以下是辅助变量***************************************** structC { longdouble r, i;//real,imaginary C() {} C(longdouble a, longdouble b) { r = a, i = b; } C operator + (C x) { returnC(r + x.r, i + x.i); } C operator - (C x) { returnC(r - x.r, i - x.i); } C operator * (C x) { returnC(r * x.r - i * x.i, r * x.i + i * x.r); } }w[N], A[N], B[N]; int R[N];//蝴蝶变换 const db PI = acos(-1);//圆周率 //*********************************************************************************************
//*****************************************FFT板子********************************************* voidFFT(C a[], int n){ for (int i = 0; i < n; i++) if (i < R[i]) swap(a[i], a[R[i]]); for (int t = n >> 1, d = 1; d < n; d <<= 1, t >>= 1) for (int i = 0; i < n; i += (d << 1)) for (int j = 0; j < d; j++) { C tmp = w[t * j] * a[i + j + d]; a[i + j + d] = a[i + j] - tmp; a[i + j] = a[i + j] + tmp; } } //答案存储到c中 voidFFT_times(const vector <ll>& a,const vector <ll>& b, vector<ll>& c){ int n, d; for (int i = 0; i < a.size(); i++) A[i] = C(a[i], 0); for (int i = 0; i < b.size(); i++) B[i] = C(b[i], 0); for (n = 1, d = 0; n < a.size() + b.size() - 1; n <<= 1, d++); for (int i = 0; i < n; i++) { R[i] = (R[i >> 1] >> 1) | ((i & 1) << (d - 1)); w[i] = C(cos(2 * PI * i / n), sin(2 * PI * i / n)); } for (int i = a.size(); i < n; i++) A[i] = C(0, 0); for (int i = b.size(); i < n; i++) B[i] = C(0, 0); FFT(A, n), FFT(B, n); for (int i = 0; i < n; i++) A[i] = A[i] * B[i], w[i].i *= -1.0; FFT(A, n); int up = a.size() + b.size() - 1; c.resize(up);//重置 for (int i = 0; i < up; i++) c[i] = ((ll)(A[i].r / n + 0.5)); } //*********************************************************************************************
voidsolve() { int n, m; vector<ll>va, vb, vc; cin >> n >> m; for (int i = 0; i <= n; i++) { ll x; cin >> x; va.push_back(x); } for (int i = 0; i <= m; i++) { ll x; cin >> x; vb.push_back(x); } FFT_times(va, vb, vc); for (int i = 0; i < n + m + 1; i++) { cout << vc[i] << " "; } } intmain() { int t = 1; //cin >> t; while (t--) solve(); return0; }
//**************************************以下是辅助变量***************************************** structC { longdouble r, i;//real,imaginary C() {} C(longdouble a, longdouble b) { r = a, i = b; } C operator + (C x) { returnC(r + x.r, i + x.i); } C operator - (C x) { returnC(r - x.r, i - x.i); } C operator * (C x) { returnC(r * x.r - i * x.i, r * x.i + i * x.r); } }w[N], A[N], B[N]; int R[N];//蝴蝶变换 const db PI = acos(-1);//圆周率 //*********************************************************************************************
//*****************************************FFT板子********************************************* voidFFT(C a[], int n){ for (int i = 0; i < n; i++) if (i < R[i]) swap(a[i], a[R[i]]); for (int t = n >> 1, d = 1; d < n; d <<= 1, t >>= 1) for (int i = 0; i < n; i += (d << 1)) for (int j = 0; j < d; j++) { C tmp = w[t * j] * a[i + j + d]; a[i + j + d] = a[i + j] - tmp; a[i + j] = a[i + j] + tmp; } } //答案存储到c中 voidFFT_times(const vector <ll>& a,const vector <ll>& b, vector<ll>& c){ int n, d; for (int i = 0; i < a.size(); i++) A[i] = C(a[i], 0); for (int i = 0; i < b.size(); i++) B[i] = C(b[i], 0); for (n = 1, d = 0; n < a.size() + b.size() - 1; n <<= 1, d++); for (int i = 0; i < n; i++) { R[i] = (R[i >> 1] >> 1) | ((i & 1) << (d - 1)); w[i] = C(cos(2 * PI * i / n), sin(2 * PI * i / n)); } for (int i = a.size(); i < n; i++) A[i] = C(0, 0); for (int i = b.size(); i < n; i++) B[i] = C(0, 0); FFT(A, n), FFT(B, n); for (int i = 0; i < n; i++) A[i] = A[i] * B[i], w[i].i *= -1.0; FFT(A, n); int up = a.size() + b.size() - 1; c.resize(up);//重置 for (int i = 0; i < up; i++) c[i] = ((ll)(A[i].r / n + 0.5)); } //*********************************************************************************************
voidsolve() { ll n, m; cin >> n; constint maxn = 2e5+1; vector<ll>va(maxn, 0); va[0]++; for (int i = 1; i <= n; i++) { ll x; cin >> x; va[x]++; } vector<ll>vb = va; vector<ll>vc;
FFT_times(va, vb, vc); cin >> m; ll ans = 0; while (m--) { ll x; cin >> x; if (vc[x])ans++; } cout << ans << endl; } intmain() { int t = 1; //cin >> t; while (t--) solve(); return0; }
//**************************************以下是辅助变量***************************************** structC { longdouble r, i;//real,imaginary C() {} C(longdouble a, longdouble b) { r = a, i = b; } C operator + (C x) { returnC(r + x.r, i + x.i); } C operator - (C x) { returnC(r - x.r, i - x.i); } C operator * (C x) { returnC(r * x.r - i * x.i, r * x.i + i * x.r); } }w[N], A[N], B[N]; int R[N];//蝴蝶变换 const db PI = acos(-1);//圆周率 //*********************************************************************************************
//*****************************************FFT板子********************************************* voidFFT(C a[], int n){ for (int i = 0; i < n; i++) if (i < R[i]) swap(a[i], a[R[i]]); for (int t = n >> 1, d = 1; d < n; d <<= 1, t >>= 1) for (int i = 0; i < n; i += (d << 1)) for (int j = 0; j < d; j++) { C tmp = w[t * j] * a[i + j + d]; a[i + j + d] = a[i + j] - tmp; a[i + j] = a[i + j] + tmp; } } //答案存储到c中 voidFFT_times(const vector <ll>& a,const vector <ll>& b, vector<ll>& c){ int n, d; for (int i = 0; i < a.size(); i++) A[i] = C(a[i], 0); for (int i = 0; i < b.size(); i++) B[i] = C(b[i], 0); for (n = 1, d = 0; n < a.size() + b.size() - 1; n <<= 1, d++); for (int i = 0; i < n; i++) { R[i] = (R[i >> 1] >> 1) | ((i & 1) << (d - 1)); w[i] = C(cos(2 * PI * i / n), sin(2 * PI * i / n)); } for (int i = a.size(); i < n; i++) A[i] = C(0, 0); for (int i = b.size(); i < n; i++) B[i] = C(0, 0); FFT(A, n), FFT(B, n); for (int i = 0; i < n; i++) A[i] = A[i] * B[i], w[i].i *= -1.0; FFT(A, n); int up = a.size() + b.size() - 1; c.resize(up);//重置 for (int i = 0; i < up; i++) c[i] = ((ll)(A[i].r / n + 0.5)); } //*********************************************************************************************
constint MAXN = 1e5 + 2;
ll n, q; ll p[MAXN]; bool biaoji[MAXN]; vector<ll>circle[MAXN];//第i个圈的人 vector<ll>cnt[N];//存储第i个圈的贡献 voidsolve() { int numCircle = 0; cin >> n >> q; for (int i = 1; i <= n; i++) { cin >> p[i];//指向 } for (int i = 1; i <= n; i++) { if (biaoji[i])continue; ++numCircle; int now = i; while (!biaoji[now]) { biaoji[now] = 1; circle[numCircle].push_back(now); now = p[now]; } //做一遍fft vector<ll>tmp = circle[numCircle]; tmp.insert(tmp.end(), circle[numCircle].begin(), circle[numCircle].end());//扩大到两倍 reverse(circle[numCircle].begin(), circle[numCircle].end());//反转(这是fft的一个技巧) FFT_times(circle[numCircle], tmp, cnt[numCircle]);//将贡献累计到cnt中 }
//此时一共有numCircle个圈,并且贡献都存储到了cnt中,接下来要将(等长度)的cnt汇总
memset(p, 0, sizeof p); vector<ll>si(numCircle+1);//记录每一种圈的原始圈长度 int now = 0; for (int i = 1; i <= numCircle; i++) { int siz = circle[i].size(); if (!p[siz]) { cnt[++now] = cnt[i]; si[now] = siz; p[siz] = now;//记录这个siz对应的cnt编号 } else { int last = p[siz]; for (int j = 0; j < cnt[i].size(); j++) { cnt[last][j] += cnt[i][j];//累加贡献 } } } //此时有now种圈,now不超过根号n个
while (q--) { ll z; cin >> z; ll ans = 0; for (int i = 1; i <= now; i++) {//遍历now种圈 int siz = si[i]; int p = z%siz; ans += cnt[i][siz - 1 + p]; } cout << ans << endl; }
} intmain() { int t = 1; //cin >> t; while (t--) solve(); return0; }
constint N = 5e6 + 5; //**************************************以下是辅助变量***************************************** structC { longdouble r, i;//real,imaginary C() {} C(longdouble a, longdouble b) { r = a, i = b; } C operator + (C x) { returnC(r + x.r, i + x.i); } C operator - (C x) { returnC(r - x.r, i - x.i); } C operator * (C x) { returnC(r * x.r - i * x.i, r * x.i + i * x.r); } }w[N], A[N], B[N]; int R[N];//蝴蝶变换 const db PI = acos(-1);//圆周率 //*********************************************************************************************
//*****************************************FFT板子********************************************* voidFFT(C a[], int n){ for (int i = 0; i < n; i++) if (i < R[i]) swap(a[i], a[R[i]]); for (int t = n >> 1, d = 1; d < n; d <<= 1, t >>= 1) for (int i = 0; i < n; i += (d << 1)) for (int j = 0; j < d; j++) { C tmp = w[t * j] * a[i + j + d]; a[i + j + d] = a[i + j] - tmp; a[i + j] = a[i + j] + tmp; } } //答案存储到c中 voidFFT_times(const vector <db>& a, const vector <db>& b, vector<db>& c){ int n, d; for (int i = 0; i < a.size(); i++) A[i] = C(a[i], 0); for (int i = 0; i < b.size(); i++) B[i] = C(b[i], 0); for (n = 1, d = 0; n < a.size() + b.size() - 1; n <<= 1, d++); for (int i = 0; i < n; i++) { R[i] = (R[i >> 1] >> 1) | ((i & 1) << (d - 1)); w[i] = C(cos(2 * PI * i / n), sin(2 * PI * i / n)); } for (int i = a.size(); i < n; i++) A[i] = C(0, 0); for (int i = b.size(); i < n; i++) B[i] = C(0, 0); FFT(A, n), FFT(B, n); for (int i = 0; i < n; i++) A[i] = A[i] * B[i], w[i].i *= -1.0; FFT(A, n); int up = a.size() + b.size() - 1; c.resize(up);//重置 for (int i = 0; i < up; i++) c[i] = (A[i].r / n); } //*********************************************************************************************
intmain() { int n; cin >> n; vector<db>va(n + 1);//q(i) for (int i = 1; i <= n; i++) { cin >> va[i]; } vector<db>vb(n + 1);//g(i)=1/i^2 for (int i = 1; i <= n; i++) { vb[i] = (double)1.0 / i / i; } //先计算前面的,答案保存在vc1[j]中 vector<db>vc1; FFT_times(va, vb, vc1);
//*************************NTT************************** constint MAXN = 3 * 1e6 + 10; const ll P = 998244353, G = 3, Gi = 332748118; ll A[MAXN], B[MAXN],R[MAXN];//辅助数组
ll qmi(ll a, ll k){//快速幂 ll ans = 1; while (k) { if (k & 1) ans = (ans * a) % P; a = (a * a) % P; k >>= 1; } return ans % P; }
//n为数组长度,type=1为正变换,-1为逆变换 voidNTT(ll A[], int n,int type){ for (int i = 0; i < n; i++) if (i < R[i]) swap(A[i], A[R[i]]);
for (int mid = 1; mid < n; mid <<= 1) { ll Wn = qmi(type == 1 ? G : Gi, (P - 1) / (mid << 1)); for (int j = 0; j < n; j += (mid << 1)) { ll w = 1; for (int k = 0; k < mid; k++, w = (w * Wn) % P) { int x = A[j + k], y = w * A[j + k + mid] % P; A[j + k] = (x + y) % P, A[j + k + mid] = (x - y + P) % P; } } } } //c=a*b voidNTT_times(const vector<ll>& a, const vector<ll>& b, vector<ll>& c){ int n, d; for (int i = 0; i < a.size(); i++) A[i] = a[i]; for (int i = 0; i < b.size(); i++) B[i] = b[i]; for (n = 1, d = 0; n < a.size() + b.size() - 1; n <<= 1, d++); for (int i = 0; i < n; i++) { R[i] = (R[i >> 1] >> 1) | ((i & 1) << (d - 1)); } for (int i = a.size(); i < n; i++) A[i] = 0; for (int i = b.size(); i < n; i++) B[i] = 0; NTT(A, n, 1), NTT(B, n, 1); for (int i = 0; i < n; i++) A[i] = A[i] * B[i]%P; NTT(A, n, -1); int up = a.size() + b.size() - 1; c.resize(up);//重置 ll inv = qmi(n, P - 2); for (int i = 0; i < up; i++) c[i] =A[i]*inv%P; } //************************************************************** intmain(){ int n, m; cin >> n >> m; vector<ll>va(n+1),vb(m+1); for (int i = 0; i <= n; i++) { cin >> va[i]; } for (int i = 0; i <= m; i++) { cin >> vb[i]; } vector<ll>vc; NTT_times(va, vb, vc); for (auto i : vc) { cout << i << " "; } return0; }
constint G = 3,P = 998244353; inlineintqpow(int a,int b){ int re = 1; for (; b; b >>= 1,a = 1ll * a * a % P) if (b & 1) re = 1ll * re * a % P; return re; } int R[maxn],c[maxn]; voidNTT(int* a,int n,int f){ for (int i = 0; i < n; i++) if (i < R[i]) swap(a[i],a[R[i]]); for (int i = 1; i < n; i <<= 1){ int gn = qpow(G,(P - 1) / (i << 1)); for (int j = 0; j < n; j += (i << 1)){ int g = 1,x,y; for (int k = 0; k < i; k++,g = 1ll * g * gn % P){ x = a[j + k],y = 1ll * g * a[j + k + i] % P; a[j + k] = (x + y) % P,a[j + k + i] = (x + P - y) % P; } } } if (f == 1) return; int nv = qpow(n,P - 2); reverse(a + 1,a + n); for (int i = 0; i < n; i++) a[i] = 1ll * a[i] * nv % P; } //a=a*b voidconv(int* a,int* b,int deg1,int deg2){ int n = 1,L = 0; while (n <= (deg1 + deg2)) n <<= 1,L++; for (int i = 1; i < n; i++) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1)); for (int i = 1; i <= deg2; i++) c[i] = b[i]; for (int i = deg2 + 1; i < n; i++) c[i] = 0; c[0] = 0; NTT(a,n,1); NTT(c,n,1); for (int i = 0; i < n; i++) a[i] = 1ll * a[i] * c[i] % P; NTT(a,n,-1); }