Description
给出一个长度为n的序列A,定义一个非空集合S的价值为这个集合第min{|S|,k}大的数,定义一个序列的价值为这个序列的所有非空子集价值之和,对[1,n]中任一k,求A序列的价值
Input
第一行一整数T表示用例组数,每组用例首先输入一整数n表示序列长度,之后n个整数Ai表示该序列(1<=T<=10,1<=n<=10^5,0<=Ai<=10^9)
Output
对于每组用例,输出k个整数分别表示对任一k,A序列的价值,结果模 998244353
Sample Input
2
3
1 1 1
5
1 2 3 4 5
Sample Output
7 11 12
129 201 231 239 240
Solution
定义ans[k]为A序列所有非空子集第k大元素之和(如果某子集元素个数小于k则不考虑),先给A序列从小到大排序,考虑每个Ai作为第k大的数时对ans[k]的贡献,那么有
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define maxn 111111
#define mod 998244353
#define g 3
ll wn[22],iwn[22];
ll mul(ll a,ll b,ll p)
{
//return (a*b-(ll)(a/(ld)p*b+1e-3)*p+p)%p;
return a*b%p;
}
ll mod_pow(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)ans=mul(ans,a,p);
a=mul(a,a,p);
b>>=1;
}
return ans;
}
int pos[4*maxn];
void fft_init(int len)
{
int j=0;
while((1<<j)<len)j++;
j--;
for(int i=0;i<len;i++)
pos[i]=pos[i>>1]>>1|((i&1)<<j);
}
void ntt(ll *x,int len,int sta)
{
for(int i=0;i<len;i++)
if(i<pos[i])swap(x[i],x[pos[i]]);
for(int m=2,now=1;m<=len;now++,m<<=1)
{
ll Wn=wn[now];
//ll Wn=mod_pow(g,(mod-1)/m,mod);
if(sta==-1)Wn=iwn[now];
ll W=1;
for(int k=0;k<m/2;k++,W=mul(W,Wn,mod))
{
for(int i=k;i<len;i+=m)
{
ll temp=mul(W,x[i+m/2],mod);
x[i+m/2]=x[i]-temp<0?x[i]-temp+mod:x[i]-temp;
x[i]=x[i]+temp>=mod?x[i]+temp-mod:x[i]+temp;
}
}
}
if(sta==-1)
{
ll temp=mod_pow(len,mod-2,mod);
for(int i=0;i<len;i++)x[i]=mul(x[i],temp,mod);
}
}
void NTT(ll *a,ll *b,int len1,int len2)
{
int len=1;
while(len<len1+len2)len<<=1;
fft_init(len);
for(int i=len1;i<len;i++)a[i]=0;
for(int i=len2;i<len;i++)b[i]=0;
ntt(a,len,1),ntt(b,len,1);
for(int i=0;i<len;i++)a[i]=mul(a[i],b[i],mod);
ntt(a,len,-1);
}
ll f[maxn],b[maxn],inv[maxn];
void init()
{
f[0]=b[0]=inv[0]=1;
for(int i=1;i<maxn;i++)
{
b[i]=2ll*b[i-1]%mod;
f[i]=1ll*i*f[i-1]%mod;
inv[i]=mod_pow(f[i],mod-2,mod);
}
int j=18;
wn[j+1]=mod_pow(g,(mod-1)/(1<<(j+1)),mod);
for(int i=j;i>=0;i--)wn[i]=mul(wn[i+1],wn[i+1],mod);
iwn[j+1]=mod_pow(wn[j+1],mod-2,mod);
for(int i=j;i>=0;i--)iwn[i]=mul(iwn[i+1],iwn[i+1],mod);
}
bool cmp(ll a,ll b)
{
return a>b;
}
int T,n;
ll a[maxn],A[4*maxn],B[4*maxn],ans[maxn];
int main()
{
init();
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%I64d",&a[i]);
sort(a,a+n,cmp);
for(int i=0;i<n;i++)A[n-i-1]=a[i]*f[i]%mod*b[n-i-1]%mod;
for(int i=0;i<n;i++)B[i]=inv[i];
NTT(A,B,n,n);
for(int i=1;i<=n;i++)ans[i]=A[n-i]*inv[i-1]%mod;
for(int i=2;i<=n;i++)ans[i]=(ans[i]+ans[i-1])%mod;
for(int i=1;i<=n;i++)printf("%I64d ",ans[i]);
printf("\n");
}
return 0;
}