QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#116543 | #6513. Expression 3 | wangyian2022 | TL | 2515ms | 61444kb | C++14 | 6.7kb | 2023-06-29 14:47:21 | 2023-06-29 14:47:22 |
Judging History
answer
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cassert>
#include<random>
const int Q=1<<19|5;
const int INF=(1<<30);
const int mod=998244353,G=3,iG=(mod+1)/G,i2=(mod+1)/2,img=911660635;
typedef long long ll;
#define rg register int
#define cint const register int
//char ibuf[1<<21],*IP1=ibuf,*IP2=ibuf;
//#define gc() (__builtin_expect(IP1==IP2,0)&&(IP2=(IP1=ibuf)+fread(ibuf,1,1<<21,stdin),__builtin_expect(IP1==IP2,0))?EOF:*IP1++)
#define gc getchar
#define pc putchar
inline bool ig(const char c){return c>=48&&c<=57;}
inline void read(rg&oi){char c;rg f=1,res=0;while(c=gc(),(!ig(c))&&c^'-');c^'-'?res=(c^48):f=-1;while(c=gc(),ig(c))res=res*10+(c^48);oi=f*res;}
inline void print(rg oi){char io[23];rg l=0;if(oi<0)pc('-'),oi=~oi+1;do io[++l]=(oi%10+48);while(oi/=10);for(;l;--l)pc(io[l]);}
inline void write(cint oi,const char c){print(oi);pc(c);}char _ST_;
inline void swap(rg&x,rg&y){cint t=x;x=y;y=t;}
int prd[Q],ivp[Q];
inline int inc(cint x,cint y){return x+y<mod?x+y:x+y-mod;}
inline int dec(cint x,cint y){return x>=y?x-y:x-y+mod;}
inline int mul(cint x,cint y){return 1ll*x*y%mod;}
inline void Inc(rg&x,cint y){((x+=y)>=mod)&&(x-=mod);}
inline void Dec(rg&x,cint y){((x-=y)<0)&&(x+=mod);}
inline void Mul(rg&x,cint y){x=1ll*x*y%mod;}
inline int pow(rg x,rg y){rg res=1;for(;y;y>>=1,Mul(x,x))(y&1)&&(Mul(res,x),1);return res;}
inline int Inv(cint x){return pow(x,mod-2);}
inline int binom(cint N,cint M){return N<M||N<0||M<0?0:mul(prd[N],mul(ivp[M],ivp[N-M]));}
int n,a[Q],b[Q],c[Q];
inline int max(cint x,cint y){return x>y?x:y;}
inline int min(cint x,cint y){return x<y?x:y;}
//Memory:15N
namespace poly{
int rev[Q],*gp[25],*igp[25];
int A[Q],B[Q],C[Q];
//to init before NTT or INTT
//the time complexity is O(N)
inline void init(cint N,cint lgN){
for(rg i=0;i<N;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lgN-1));
for(rg i=1,ct=0;i<N;i<<=1,++ct){
delete gp[ct];gp[ct]=new int[i];gp[ct][0]=1;gp[ct][1]=pow(G,(mod-1)/(i<<1));
for(rg j=2;j<i;++j)gp[ct][j]=mul(gp[ct][j-1],gp[ct][1]);
}
for(rg i=1,ct=0;i<N;i<<=1,++ct){
delete igp[ct];igp[ct]=new int[i];igp[ct][0]=1;igp[ct][1]=pow(iG,(mod-1)/(i<<1));
for(rg j=2;j<i;++j)igp[ct][j]=mul(igp[ct][j-1],igp[ct][1]);
}
}
//change coefficient of f to f(w_N^0),f(w_N^1),...f(w_N^{N-1})
//the time complexity is O(NlogN)
inline void NTT(rg*f,cint N){
for(rg i=0;i<N;++i)if(i<rev[i])swap(f[i],f[rev[i]]);
for(rg i=1,ct=0;i<N;i<<=1,++ct){
for(rg j=0;j<N;j+=(i<<1)){
cint*w=igp[ct];rg*f0=&f[j],*f1=&f[j|i];
for(rg k=0;k<i;++k){
cint A=*f0,B=mul(*f1,*w++);*f0++=inc(A,B);*f1++=dec(A,B);
}
}
}
}
//change f(w_N^0),f(w_N^1),...f(w_N^{N-1}) to the coefficient of f
//the time complexity is O(NlogN)
inline void INTT(rg*f,cint N){
for(rg i=0;i<N;++i)if(i<rev[i])swap(f[i],f[rev[i]]);
for(rg i=1,ct=0;i<N;i<<=1,++ct){
for(rg j=0;j<N;j+=(i<<1)){
cint*w=gp[ct];rg*f0=&f[j],*f1=&f[j|i];
for(rg k=0;k<i;++k){
cint A=*f0,B=mul(*f1,*w++);*f0++=inc(A,B);*f1++=dec(A,B);
}
}
}
cint iN=Inv(N);for(rg i=0;i<N;++i)f[i]=mul(f[i],iN);
}
//for f,g,deg f=n,deg g=h,calculate h=f*g
//the time complexity is O(NlogN)
inline void Gconv(cint*const f,cint n,cint*const g,cint m,rg*h){
rg N=1,lgN=0;cint Len=n+m-1;for(;N<Len;N<<=1,++lgN);init(N,lgN);
for(rg i=0;i<N;++i)A[i]=B[i]=0;for(rg i=0;i<n;++i)A[i]=f[i];
for(rg i=0;i<m;++i)B[i]=g[i];NTT(A,N);NTT(B,N);
for(rg i=0;i<N;++i)A[i]=mul(A[i],B[i]);INTT(A,N);for(rg i=0;i<Len;++i)h[i]=A[i];
}
//for f,deg f=n,do \forall i\in [0,N-1(N>=n*2,N=2^k)],f_i=0
//the time complexity is O(N)
inline void clear(rg*f,cint n){rg N=1;for(;N<n<<1;N<<=1);for(rg i=0;i<N;++i)f[i]=0;}
//for f,deg f=n,calculate g(x)=f'(x)
//the time complexity is O(N)
inline void Gder(cint*const f,cint n,rg*g){for(rg i=1;i<n;++i)g[i-1]=mul(f[i],i);g[n-1]=0;}
//for f,deg f=n,calculate g(x)=\int f(x)
//the time complexity is O(N)
inline void Gint(cint*const f,cint n,rg*g){for(rg i=0;i<n;++i)g[i+1]=mul(f[i],Inv(i+1));g[0]=0;}
//for f,deg f=n,calculate f(x)g(x)\equiv 1\pmod x^n
//the time complexity is O(NlogN)
//promise [x^0]f(x)\neq 0
inline void Ginv(cint*const f,cint n,rg*g){
clear(g,n);clear(B,n);g[0]=Inv(f[0]);rg N=1,lgL=1;
for(;N<n<<1;N<<=1,++lgL){
cint Len=N<<1;for(rg i=0;i<Len;++i)B[i]=0;
for(rg i=0;i<N;++i)B[i]=f[i];init(Len,lgL);
NTT(g,Len);NTT(B,Len);for(rg i=0;i<Len;++i)g[i]=mul(g[i],dec(2,mul(g[i],B[i])));
INTT(g,Len);for(rg i=N;i<Len;++i)g[i]=0;
}
}
//for f,deg f=n,g,deg g=m,calculate f(x)=g(x)q(x)+r(x),deg q=n-m+1,deg r=m-1
//the time complexity is O(NlogN)
inline void Gdiv(cint*const f,cint n,cint*const g,cint m,rg*q,rg*r){
if(m>n){for(rg i=0;i<n;++i)r[i]=f[i];return;}
clear(A,n);clear(B,n);clear(C,n);
for(rg i=0;i<m;++i)A[i]=g[i];std::reverse(A,A+m);cint Len=n-m+1;
Ginv(A,Len,C);for(rg i=0;i<n;++i)A[i]=f[i];std::reverse(A,A+n);
for(rg i=0;i<Len;++i)B[i]=C[i];
rg N=1,lgN=0;for(;N<Len<<1;N<<=1,++lgN);init(N,lgN);
for(rg i=Len;i<N;++i)A[i]=B[i]=0;
NTT(A,N);NTT(B,N);for(rg i=0;i<N;++i)A[i]=mul(A[i],B[i]);INTT(A,N);
for(rg i=0;i<Len;++i)q[i]=A[i];std::reverse(q,q+Len);
for(;N<n;N<<=1,++lgN);init(N,lgN);
for(rg i=0;i<m;++i)A[i]=g[i];for(rg i=m;i<N;++i)A[i]=0;
for(rg i=0;i<Len;++i)B[i]=q[i];for(rg i=Len;i<N;++i)B[i]=0;
NTT(A,N);NTT(B,N);for(rg i=0;i<N;++i)A[i]=mul(A[i],B[i]);INTT(A,N);
for(rg i=0;i<m-1;++i)r[i]=dec(f[i],A[i]);
}
int*f[Q<<2],*g[Q<<2],h[Q];
inline void bld(cint l,cint r,cint x){
f[x]=new int[r-l+2];g[x]=new int[r-l+2];
if(l==r)return f[x][0]=mod-c[l],f[x][1]=1,g[x][0]=mod-l,g[x][1]=1,void();
cint mid=l+r>>1;bld(l,mid,x<<1);bld(mid+1,r,x<<1|1);
Gconv(f[x<<1],mid-l+2,f[x<<1|1],r-mid+1,f[x]);
Gconv(g[x<<1],mid-l+2,g[x<<1|1],r-mid+1,g[x]);
}
int t1[Q],t2[Q],t3[Q];
inline void calc(cint l,cint r,cint x){
if(l==r)return c[l]=b[l]>0?h[l]:dec(0,h[l]),void();cint mid=l+r>>1;
for(rg i=l;i<=r;++i)t1[i-l]=h[i];
Gdiv(t1,r-l+1,g[x<<1],mid-l+2,t2,t3);
for(rg i=l;i<=mid;++i)h[i]=t3[i-l];
Gconv(t1,r-l+1,f[x<<1],mid-l+2,t1);
Gdiv(t1,r-l+1+mid-l+2-1,g[x<<1|1],r-mid+1,t2,t3);
for(rg i=mid+1;i<=r;++i)h[i]=t3[i-mid-1];
calc(l,mid,x<<1);calc(mid+1,r,x<<1|1);
}
inline void solve(){
prd[0]=ivp[0]=1;for(rg i=1;i<=n;++i)prd[i]=mul(prd[i-1],i);
ivp[n]=Inv(prd[n]);for(rg i=n-1;i>=1;--i)ivp[i]=mul(ivp[i+1],i+1);
for(rg i=1;i<n;++i)c[i]=i-b[i];bld(1,n-1,1);h[1]=1;calc(1,n-1,1);rg res=a[1];
for(rg i=1;i<n;++i)Inc(res,mul(c[i],mul(a[i+1],ivp[i])));write(mul(res,prd[n-1]),'\n');
}
}
char _ED_;int main(){
fprintf(stderr,"memory:%llu MB\n",(&_ST_-&_ED_)>>20);
read(n);for(rg i=1;i<=n;++i)read(a[i]),a[i]%=mod;{
char c;while(c=gc(),c^'+'&&c^'-');b[1]=(c=='-'?-1:1);
for(rg i=2;i<n;++i)c=gc(),b[i]=(c=='-'?-1:1);}poly::solve();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 29652kb
input:
4 9 1 4 1 -+-
output:
46
result:
ok 1 number(s): "46"
Test #2:
score: 0
Accepted
time: 2ms
memory: 29644kb
input:
5 1 2 3 4 5 +-+-
output:
998244313
result:
ok 1 number(s): "998244313"
Test #3:
score: 0
Accepted
time: 2515ms
memory: 61444kb
input:
100000 664815434 205025136 871445392 797947979 379688564 336946672 231295524 401655676 526374414 670533644 156882283 372427821 700299596 166140732 677498490 44858761 185182210 559696133 813911251 842364231 681916958 114039865 222372111 784286397 437994571 152137641 650875922 613727135 209302742 5321...
output:
178167352
result:
ok 1 number(s): "178167352"
Test #4:
score: -100
Time Limit Exceeded
input:
200000 109044620 745578941 396599814 756923982 940933214 875346257 378089839 792684563 491924893 782192923 208569108 421583135 814903710 690275542 15773609 364566266 12890134 661702679 640270667 615999192 13352194 325560419 385152885 265008089 570536451 282429805 331946208 255056541 813809151 150995...