結果
問題 | No.1068 #いろいろな色 / Red and Blue and more various colors (Hard) |
ユーザー |
|
提出日時 | 2021-02-14 14:42:05 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,294 ms / 3,500 ms |
コード長 | 2,448 bytes |
コンパイル時間 | 927 ms |
コンパイル使用メモリ | 81,348 KB |
実行使用メモリ | 47,452 KB |
最終ジャッジ日時 | 2024-07-21 23:02:45 |
合計ジャッジ時間 | 25,237 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 29 |
ソースコード
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<vector> #include<algorithm> using namespace std; typedef long long LL; typedef unsigned int uint; LL ww[101]; LL* e = ww + 50; const int MAXN=2e5+5; const LL P=998244353; LL qpow(LL a,LL k, LL p){ LL c=1; a %= p; while(k){ if(k&1) c=(c*a)%p; k >>= 1; a = (a*a)%p; } return c; } void ntt_initial(LL* e, const LL& P, const LL& g) { int s = 0; LL q = P - 1; while ((q & 1) == 0) {s++; q >>= 1;} LL w = qpow(g, q, P); LL invw = qpow(w, P - 2, P); for (int h = s; h >= 0; h--) { e[h] = w; e[-h] = invw; w = (w * w) % P; invw = (invw * invw) % P; } } void ntt(LL* f, const int& h, const int& type) { if (h == 0) return; LL f0[1 << (h - 1)], f1[1 << (h - 1)]; int n = 1 << h; for (int i = 0; i < n; i+=2) f0[i/2] = f[i]; ntt(f0, h - 1, type); for (int i = 1; i < n; i+=2) f1[i/2] = f[i]; ntt(f1, h - 1, type); LL w = e[type * h]; LL x = 1; for (int k = 0; k < n / 2; k++) { f[k] = f0[k] + x * f1[k]; f[k] %= P; f[k + n / 2] = f0[k] - x * f1[k]; f[k + n / 2] %= P; x *= w; x %= P; } } LL A[MAXN]; vector<LL> f[MAXN]; LL F1[MAXN*4],F2[MAXN*4]; void mul(int i1,int i2){ int limit=f[i1].size()+f[i2].size()-1; int deg=1,h=0; while(deg<limit) {deg<<=1;h++;} for(uint i=0;i<f[i1].size();i++) F1[i]=f[i1][i]; for(int i=f[i1].size();i<deg;i++) F1[i]=0; for(uint i=0;i<f[i2].size();i++) F2[i]=f[i2][i]; for(int i=f[i2].size();i<deg;i++) F2[i]=0; ntt(F1,h,1);ntt(F2,h,1); for(int i=0;i<deg;i++) F1[i]=F1[i]*F2[i]%P; ntt(F1,h,-1); LL inv = qpow(deg, P - 2, P); for (int i = 0; i < deg; i++) { F1[i] = ((F1[i] * inv) % P + P)%P; } f[i1].clear(); for(int i=0;i<limit;i++) f[i1].push_back(F1[i]); } int main(){ ntt_initial(e,P,3); int n,Q; int B; scanf("%d%d",&n,&Q); for(int i=0;i<n;i++){ scanf("%lld",A+i); A[i]%=P; f[i].push_back(A[i]-1); f[i].push_back(1); } while(n>1){ for(int i=0;i<n/2;i++){ mul(i,i+n/2); } if(n&1){ f[n/2]=f[n-1]; n=n/2+1; } else{ n=n/2; } } for(int i=0;i<Q;i++){ scanf("%d",&B); cout<<f[0][B]<<endl; } return 0; }