QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#116467 | #6513. Expression 3 | serene_analysis | WA | 14ms | 65244kb | C++14 | 4.3kb | 2023-06-29 11:48:04 | 2023-06-29 11:48:06 |
Judging History
answer
#include<algorithm>
#include<cstdio>
#include<vector>
const int maxn=8e5+5;
const int mod=998244353;
const int g=3,ginv=(mod+1)/g;
int inv[maxn],fact[maxn],finv[maxn];
void init(){
inv[0]=inv[1]=fact[0]=fact[1]=finv[0]=finv[1]=1;
for(int i=2;i<=maxn-2;i++){
inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
fact[i]=1ll*fact[i-1]*i%mod;
finv[i]=1ll*finv[i-1]*inv[i]%mod;
}
return;
}
int qpow(int a,int b,int mod){
int ans=1;
while(b){
if(b&1)ans=1ll*ans*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return ans;
}
int rev[maxn];
void rev_init(int n,int cou){
for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cou-1));
return;
}
struct poly{
std::vector<int>pol;
void sizen(int k){
pol.resize(k);
return;
}
int& operator[](int x){
if(1u*x>=pol.size())printf("std::bad_alloc,x=%d,size=%d\n",x,(int)pol.size());
return pol.at(x);
}
void out(){
int nlen=pol.size();
for(int i=0;i<nlen;i++)printf("pol[%d]=%d\n",i,pol[i]);
return;
}
void ntt(int n,int type){
for(int i=0;i<n;i++)if(i<rev[i])std::swap(pol[i],pol[rev[i]]);
for(int mid=1;mid<n;mid<<=1){
int nr=2*mid,step=qpow(type==1?g:ginv,(mod-1)/nr,mod);
for(int i=0;i<n;i+=nr){
int now=1;
for(int j=0;j<mid;j++){
int lef=pol[i+j],rig=1ll*now*pol[i+j+mid]%mod;
pol[i+j]=(lef+rig)%mod,pol[i+j+mid]=(lef-rig+mod)%mod;
now=1ll*now*step%mod;
}
}
}
return;
}
void prev(){
std::reverse(pol.begin(),pol.end());
return;
}
poly cut(int k){
poly ret;
ret.sizen(k);
int nlen=pol.size();
for(int i=0;i<k;i++)if(i<nlen)ret[i]=pol[i];
return ret;
}
};
poly mul(poly now,poly oth){
int n=now.pol.size(),m=oth.pol.size();
poly ret;
ret.sizen(n+m-1);
int nlen=std::max(n,m),cou=0;
m=n+m-1,n=1;
while(n<=2*nlen)n*=2,cou++;
rev_init(n,cou),now.sizen(n),oth.sizen(n);
now.ntt(n,1),oth.ntt(n,1);
for(int i=0;i<n;i++)now[i]=1ll*now[i]*oth[i]%mod;
now.ntt(n,-1);
int ninv=qpow(n,mod-2,mod);
for(int i=0;i<m;i++)ret[i]=1ll*now[i]*ninv%mod;
return ret;
}
poly pinv(poly gave,int n){
poly ret;
ret.sizen(1),ret[0]=qpow(gave[0],mod-2,mod);
for(int i=1;i<n;i<<=1){
poly now,oth=mul(mul(gave.cut(2*i),ret).cut(2*i),ret).cut(2*i);
now.sizen(2*i),ret.sizen(2*i);
for(int j=0;j<i;j++)now[j]=2*ret[j]%mod;
for(int j=0;j<2*i;j++)ret[j]=(now[j]-oth[j]+mod)%mod;
}
return ret.cut(n);
}
poly dec(poly now,poly oth){
int nlen=std::max(now.pol.size(),oth.pol.size());
now.sizen(nlen),oth.sizen(nlen);
for(int i=0;i<nlen;i++)(now[i]+=mod-oth[i])%=mod;
return now;
}
poly pmod(poly lef,poly rig){
int n=lef.pol.size()+1,m=rig.pol.size()+1;
if(n<m)return /*printf("n=%d,m=%d\n",n,m),*/lef;
lef.prev(),rig.prev();
poly dv=mul(lef.cut(n-m+1),pinv(rig,n-m+1)).cut(n-m+1);
lef.prev(),rig.prev(),dv.prev();
// printf("dv:"),dv.out();
return dec(lef,mul(rig,dv)).cut(m-1);
}
struct node{
int l,r;
poly nv,nmod;
}tree[maxn];
int a[maxn],sgn[maxn],c[maxn];
void build(int i,int l,int r){
tree[i].l=l,tree[i].r=r;
if(l==r){
poly now,oth;
now.sizen(2),oth.sizen(2),now[1]=oth[1]=1,now[0]=mod-l,oth[0]=mod-c[l];
tree[i].nv=oth,tree[i].nmod=now;
return;
}
int mid=(l+r)>>1;
build(i*2,l,mid),build(i*2+1,mid+1,r);
tree[i].nv=mul(tree[i*2].nv,tree[i*2+1].nv);
tree[i].nmod=mul(tree[i*2].nmod,tree[i*2+1].nmod);
return;
}
int ans;
void go(int i,poly gave){
// printf("go:%d\n",i);
// gave.out();
if(tree[i].l==tree[i].r){
int ni=tree[i].l;
(ans+=1ll*a[ni]*finv[ni-1]%mod*gave[0]%mod)%=mod;
return;
}
// printf("lmod:"),tree[i*2].nmod.out();
// printf("rmod:"),tree[i*2+1].nmod.out();
// printf("lv:"),tree[i*2].nv.out();
go(i*2,pmod(gave,tree[i*2].nmod)),go(i*2+1,pmod(mul(gave,tree[i*2].nv),tree[i*2+1].nmod));
return;
}
void test(){
poly fir,sec;
fir.sizen(3),sec.sizen(2),fir[0]=fir[2]=sec[0]=1,fir[1]=sec[1]=2;
mul(fir,sec).out();
mul(pinv(fir,3),fir).out();
pmod(mul(fir,sec),fir).out();
return;
}
int n;
signed main(){
test();
init();
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",a+i);
scanf("\n");
for(int i=1;i<=n-1;i++){
sgn[i]=(getchar()=='+'?1:mod-1),c[i]=(i+1+mod-sgn[i])%mod;
// printf("sgn[%d]=%d,c[i]=%d\n",i,sgn[i],c[i]);
}
poly one;
one.sizen(1),one[0]=1;
build(1,1,n),go(1,one);
printf("%lld",1ll*fact[n-1]*ans%mod);
return 0;
}
/*
4
9 1 4 1
-+-
*/
//namespace burningContract
詳細信息
Test #1:
score: 0
Wrong Answer
time: 14ms
memory: 65244kb
input:
4 9 1 4 1 -+-
output:
pol[0]=1 pol[1]=4 pol[2]=5 pol[3]=2 pol[0]=1 pol[1]=0 pol[2]=0 pol[3]=4 pol[4]=3 pol[0]=0 pol[1]=0 pol[2]=0 46
result:
wrong output format Expected integer, but "pol[0]=1" found