Rikka with Subset ( NTT 练习)
作者:互联网
题目: http://acm.hdu.edu.cn/showproblem.php?pid=5829
参考 https://blog.csdn.net/hdxrie/article/details/80961416?utm_source=blogxgwz3
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define LL long long #define ULL unsigned long long #define rep(i,j,k) for(int i=j;i<=k;i++) #define dep(i,j,k) for(int i=k;i>=j;i--) #define INF 0x3f3f3f3f #define mem(i,j) memset(i,j,sizeof(i)) #define make(i,j) make_pair(i,j) #define pb push_back using namespace std; const LL p = 998244353, N = (1 << 18) + 5, G = 3, Gi = 332748118; LL ksm(LL a,LL b) { LL ans = 1; while(b) { if(b & 1) ans = ans * a % p; a = a * a % p; b >>= 1; } return ans; } int n, m; LL limit, a[N], b[N], r[N], l; void NTT(LL *A, int type) { rep(i, 0, limit - 1) if(i < r[i]) swap(A[i], A[r[i]]); for(int mid = 1; mid < limit; mid <<= 1) { LL Wn = ksm(type == 1 ? G : Gi, (p - 1) / (mid << 1) ); for(int j = 0;j < limit; 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; } } } if (type == -1) { LL inv = ksm(limit, p - 2); for (int i = 0; i < limit; i++) A[i] = 1ll * A[i] * inv % p; } } LL inv[N], fac[N], invfac[N]; void init() { invfac[0] = fac[0] = inv[1] = fac[1] = invfac[1] = 1LL; rep(i, 2, N - 1) { fac[i]=(fac[i-1]*i)%p; inv[i] = (p - p / i) * inv[p % i] % p; invfac[i] = (invfac[i - 1] * inv[i]) % p; } } LL A[N]; int main() { init(); int t; scanf("%d", &t); while( t-- ) { scanf("%d", &n); mem(a, 0); mem(b, 0); for (limit = 1, l = 0; limit <= (n << 1); l++, limit <<= 1); rep(i, 0, limit - 1) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1)); rep(i, 0, n - 1) scanf("%lld", &A[i]); sort(A, A + n,greater<LL>()); rep(i, 0, n - 1) a[i] = ksm(2, n - i) * invfac[i] % p; rep(i, 0, n - 1) b[i] = fac[i] * A[i] % p; reverse(b, b + n); NTT(a, 1); NTT(b, 1); rep(i, 0, limit - 1) a[i] = a[i] * b[i] % p; NTT(a, -1); LL ans = 0LL, preans = 0LL; LL coe = inv[2]; rep(i, 1, n) { ans = coe * invfac[i-1] % p * a[n-i] % p; ans = (ans + preans) % p; printf("%lld ",ans); coe = coe * inv[2] % p; swap(ans, preans); } puts(""); } return 0; } /*#include <cstdio> #include <cstring> #include <algorithm> #define MAXN (1<<18)+5 #define MOD 998244353LL #define g 3LL using namespace std; int n,m,L,T,A[MAXN],rev[MAXN]; long long inv[MAXN],fac[MAXN],invfac[MAXN]; long long a[MAXN],b[MAXN]; long long ans_i,pre_ans_i,coe; inline bool cmp(long long a,long long b){return a>b;} inline long long Quick_MOD(long long a,long long b) { long long res=1,base=a; while (b) { if (b&1) res=(res*base)%MOD; base=(base*base)%MOD; b>>=1; } return res; } inline void NTT(long long c[],int n,int f) { long long w,wn,x,y; for (int i=0;i<n;i++) if (i<rev[i]) swap(c[i],c[rev[i]]); for (int i=1;i<n;i<<=1) { wn=Quick_MOD(g,(MOD-1)/(i<<1)); if (!~f) wn=Quick_MOD(wn,MOD-2); for (int p=i<<1,j=0;j<n;j+=p) { w=1LL; for (int k=0;k<i;k++,w=w*wn%MOD) { x=c[j+k];y=c[j+k+i]*w%MOD; c[j+k]=(x+y)%MOD;c[j+k+i]=(x-y+MOD)%MOD; } } } if (!~f) for (int i=0;i<n;i++) c[i]=c[i]*inv[n]%MOD; return ; } inline void PreWork() { invfac[0]=fac[0]=inv[1]=fac[1]=invfac[1]=1LL; for (int i=2;i<MAXN;i++) { fac[i]=(fac[i-1]*i)%MOD; inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD; invfac[i]=(invfac[i-1]*inv[i])%MOD; } return ; } inline void read(int &x) { x=0;char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return ; } int main() { PreWork(); read(T); while (T--) { memset(a,0,sizeof a);memset(b,0,sizeof b); read(n); for (m=1,L=0;m<=(n<<1);L++,m<<=1); for (int i=0;i<m;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1)); for (int i=0;i<n;i++) read(A[i]); sort(A,A+n,cmp); for (int i=0;i<n;i++) a[i]=Quick_MOD(2,n-i)*invfac[i]%MOD; for (int i=0;i<n;i++) b[i]=fac[i]*(long long)A[i]%MOD; reverse(b,b+n); NTT(a,m,1);NTT(b,m,1); for (int i=0;i<m;i++) a[i]=a[i]*b[i]%MOD; NTT(a,m,-1); ans_i=pre_ans_i=0LL;coe=inv[2]; for (int i=1;i<=n;i++) { ans_i=coe*invfac[i-1]%MOD*a[n-i]%MOD; ans_i=(ans_i+pre_ans_i)%MOD; printf("%lld ",ans_i); coe=coe*inv[2]%MOD;swap(ans_i,pre_ans_i); } putchar('\n'); } return 0; }*/View Code
标签:Subset,Rikka,int,LL,NTT,long,ans,include,define 来源: https://www.cnblogs.com/Willems/p/10984929.html