QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#951671 | #9042. Fast Bogosort | Recite to Rewrite (Jiapeng Yin, Yichen Fang, Ruheng Chen)# | AC ✓ | 439ms | 244388kb | C++14 | 20.2kb | 2025-03-26 15:29:03 | 2025-03-26 15:29:03 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <bitset>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <vector>
#include <random>
#include <chrono>
#include <string>
#include <set>
#include <queue>
#include <map>
#include <unordered_map>
using namespace std;
#define pb push_back
#define mp make_pair
typedef long long ll;
#define fi first
#define se second
#define SS 524288 //max length of DFT
#define PS (SS*20+1000) //pool for temp arrays
#define PS2 (SS*7+1000) //another pool, see ocmul
#define FS 20540416 //length of fac, rfac
const int MOD=998244353;
ll qp(ll a,ll b) {
ll ans=1; a%=MOD;
while(b)
{
if(b&1) ans=ans*a%MOD;
a=a*a%MOD; b>>=1;
}
return ans;
}
int getK(int n) {int s=1; while(s<n) s<<=1; return s;}
typedef unsigned us;
typedef unsigned long long ull;
//+ ntt
namespace RawNTT {
us pool[SS*8+10000],*ptr=pool;
us *p0[SS],*p1[SS],*q0[SS],*q1[SS],rv[SS];inline void bit_flip(us*p,int t)
{for(int i=0,j=0;i<t;++i){if(i>j) swap(p[i],p[j]);
for(int l=t>>1;(j^=l)<l;l>>=1);}}
void prep(int n){static int t=1;rv[1]=1;for(;t<n;t<<=1){
int g=qp(3,(MOD-1)/(t*2));rv[t+t]=rv[t]*(ull)((MOD+1)/2)%MOD;us*p,*q;
p=p0[t]=ptr; ptr+=max(t,16); p[0]=1;for(int m=1;m<t;++m)p[m]=p[m-1]*(ull)g%us(MOD);
bit_flip(p,t);q=q0[t]=ptr; ptr+=max(t,16);for(int i=0;i<t;++i)q[i]=(ull(p[i])<<32)/MOD;
g=qp(g,MOD-2);p=p1[t]=ptr; ptr+=max(t,16); p[0]=1;for(int m=1;m<t;++m)
p[m]=p[m-1]*(ull)g%us(MOD);bit_flip(p,t);q=q1[t]=ptr; ptr+=max(t,16);
for(int i=0;i<t;++i)q[i]=(ull(p[i])<<32)/MOD;}}typedef unsigned long long ull;
inline us my_mul(us a,us b,us c){return b*(ull)a-((ull(a)*c)>>32)*ull(998244353);}
void ntt(us* x,int n,bool f=true){prep(n); int t=n;
for(int m=1;m<n;m<<=1){t>>=1;us *p=p0[m],*q=q0[m];
us *xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t)
for(int j=0;j<t;++j){us u=xa[j]-(xa[j]>=us(MOD+MOD))*us(MOD+MOD);
us v=my_mul(xb[j],p[i],q[i]);xa[j]=u+v;xb[j]=u-v+us(MOD+MOD);}
}for(int i=0;i<n;++i)x[i]-=(x[i]>=us(MOD+MOD))*us(MOD+MOD),
x[i]-=(x[i]>=us(MOD))*us(MOD);if(f) bit_flip(x,n);}
void intt(us* x,int n,bool f=true){prep(n); int t=1;if(f) bit_flip(x,n);
for(int m=(n>>1);m;m>>=1){us *p=p1[m],*q=q1[m];
us *xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t)for(int j=0;j<t;++j)
{us u=xa[j],v=xb[j];xa[j]=u+v-(u+v>=us(MOD+MOD))*us(MOD+MOD);
xb[j]=my_mul(u-v+us(MOD+MOD),p[i],q[i]);}
t<<=1;}us rn=rv[n];for(int i=0;i<n;++i)x[i]=x[i]*(ull)rn%MOD;}}
//+ modint
union mi //modint, treat as POD
{
us w;
mi() {w=0;}
mi(us u) {w=u;}
mi(int u) {u%=MOD; w=u+((u<0)?MOD:0);}
explicit operator us() const {return w;}
explicit operator int() const {return w;}
};
mi operator + (const mi& a,const mi& b)
{return mi{a.w+b.w-((a.w+b.w>=MOD)?(MOD):0)};}
mi operator - (const mi& a,const mi& b)
{return mi{a.w-b.w+((a.w<b.w)?(MOD):0)};}
mi operator * (const mi& a,const mi& b)
{return mi{us((ull)a.w*b.w%MOD)};}
mi operator / (const mi& a,const mi& b)
{return mi{us((ull)a.w*qp(b.w,MOD-2)%MOD)};}
mi inv(const mi& a){return mi{us(qp(a.w,MOD-2))};}
bool operator == (const mi& a,const mi& b) {return a.w==b.w;}
bool operator != (const mi& a,const mi& b) {return a.w!=b.w;}
mi& operator += (mi& a,const mi& b)
{a.w=a.w+b.w-((a.w+b.w>=MOD)?MOD:0); return a;}
mi& operator -= (mi& a,const mi& b)
{a.w=a.w-b.w+((a.w<b.w)?MOD:0); return a;}
mi operator - (const mi& a) {return mi{a.w?(MOD-a.w):0};}
mi& operator ++ (mi& a) {a.w=a.w+1-((a.w+1>=MOD)?MOD:0); return a;}
mi& operator -- (mi& a) {a.w=a.w-1+(a.w?0:MOD); return a;}
void ntt(mi* x,int n,bool f=true) {RawNTT::ntt((us*)x,n,f);} //make sure this works
void intt(mi* x,int n,bool f=true) {RawNTT::intt((us*)x,n,f);}
void fft(mi* x,int n,bool r,bool f=true) {
if(r) intt(x,n,f); else ntt(x,n,f);
}
void cp(mi*t,const mi*s,int K) {
if(s) memcpy(t,s,sizeof(mi)*K);
else memset(t,0,sizeof(mi)*K);
}
void cp(mi*t,mi s,int K) {
if(s.w==0) memset(t,0,sizeof(mi)*K);
else for(int i=0;i<K;++i) t[i]=s;
}
mi qp(mi a,ll b) {
mi x=1;
while(b) {
if(b&1) x=x*a;
a=a*a; b>>=1;
}
return x;
}
string to_string(mi f) {return to_string((int)f);}
string pretty_guess(mi x,int max_dem=1000) {
string s=to_string((int)x);
auto upd=[&](string v) {
if(v.size()<s.size()) s=v;
};
upd("-"+to_string((int)(-x)));
for(int i=1;i<=max_dem;++i) {
mi w=x*i;
upd(to_string((int)w)+"/"+to_string(i));
upd("-"+to_string((int)(-w))+"/"+to_string(i));
}
return s;
}
ostream& operator << (ostream& os,const mi& m) {
os<<m.w; return os;
}
istream& operator >> (istream& is,mi& m) {
int x; is>>x; m=x; return is;
}
//+ basic ops
mi fac[FS],rfac[FS];
struct Fac_Initer {
Fac_Initer() {
fac[0]=1;
for(int i=1;i<FS;++i) fac[i]=fac[i-1]*i;
rfac[FS-1]=inv(fac[FS-1]);
for(int i=FS-1;i;--i) rfac[i-1]=rfac[i]*i;
}
}fac__initer__;
mi mempool[PS],*pt=mempool;
mi*alc(int t,bool c=0) {
if(c) cp(pt,0,t); pt+=t;
assert(pt<mempool+PS);
return pt-t;
}
void ginv_K(mi*x,mi*o,int K) {
if(K==1) {o[0]=inv(x[0]); return;}
ginv_K(x,o,K>>1);
mi*fo=alc(K,1),*fx=alc(K),*fw=alc(K);
cp(fo,o,(K>>1)); fft(fo,K,0); cp(fx,x,K); fft(fx,K,0);
for(int i=0;i<K;++i) fw[i]=fx[i]*fo[i];
fft(fw,K,1); cp(fw,fw+(K>>1),K>>1);
cp(fw+(K>>1),0,K>>1); ntt(fw,K);
for(int i=0;i<K;++i) fw[i]=fw[i]*fo[i];
fft(fw,K,1);
for(int i=0;i<(K>>1);++i) o[i+(K>>1)]=-fw[i];
pt-=K+K+K;
}
void ginv(mi*x,mi*o,int n) {
int K=getK(n);
mi *fx=alc(K,1),*fo=alc(K);
cp(fx,x,n); ginv_K(fx,fo,K);
cp(o,fo,n); pt-=K+K;
}
void gdiv(mi*a,mi*b,mi*d,int n,int m) {
int s=getK(max(n,m));
mi *ra=alc(s+s,1),*rb=alc(s+s,1);
for(int i=0;i<n;++i) ra[i]=a[n-1-i];
for(int i=0;i<m;++i) rb[i]=b[m-1-i];
ginv(rb,rb,s); fft(ra,s+s,0); fft(rb,s+s,0);
for(int i=0;i<s+s;++i) rb[i]=ra[i]*rb[i];
fft(rb,s+s,1); for(int i=0;i<=n-m;++i) d[i]=rb[n-m-i];
pt-=s*4;
}
void gdiv(mi*a,mi*b,mi*d,mi*r,int n,int m) {
gdiv(a,b,d,n,m);
int s=getK(n+1);
mi *bb=alc(s,1),*dd=alc(s,1);
cp(bb,b,m); cp(dd,d,n-m+1);
fft(bb,s,0); fft(dd,s,0);
for(int i=0;i<s;++i)
bb[i]=-bb[i]*dd[i];
fft(bb,s,1);
for(int i=0;i<m-1;++i)
r[i]=a[i]+bb[i];
pt-=s*2;
}
void gln(mi*a,mi*b,int n) {
int s=getK(n+n);
mi *ra=alc(s,1);
ginv(a,ra,n);
mi *rb=alc(s,1);
for(int i=0;i+1<n;++i)
rb[i]=a[i+1]*(i+1);
fft(ra,s,0); fft(rb,s,0);
for(int i=0;i<s;++i)
ra[i]=ra[i]*rb[i];
fft(ra,s,1); b[0]=0;
for(int i=1;i<n;++i)
b[i]=ra[i-1]*rfac[i]*fac[i-1];
pt-=s*2;
}
mi sqrt_f0;
void gsqrt_K(mi*f,mi*g,mi*h,int K,bool ch=1) {
static mi gh[SS];
if(K==1) {
assert(sqrt_f0*sqrt_f0-f[0]==0);
g[0]=sqrt_f0; h[0]=inv(sqrt_f0);
gh[0]=sqrt_f0; return;
}
gsqrt_K(f,g,h,K>>1);
mi*fh=alc(K,1),*gg=alc(K>>1),*rr=alc(K,1);
cp(fh,h,(K>>1)); fft(fh,K,0); cp(gg,gh,K>>1);
for(int i=0;i<(K>>1);++i)
gg[i]=gg[i]*gg[i];
fft(gg,K>>1,1);
for(int i=0;i<(K>>1);++i)
rr[i+(K>>1)]=gg[i]-f[i]-f[i+(K>>1)];
fft(rr,K,0);
for(int i=0;i<K;++i)
rr[i]=rr[i]*fh[i]*((MOD+1)/2);
fft(rr,K,1);
for(int i=(K>>1);i<K;++i)
g[i]=-rr[i];
if(ch) {
mi *fg=alc(K),*fw=alc(K);
cp(fg,g,K); fft(fg,K,0);
for(int i=0;i<K;++i) fw[i]=fg[i]*fh[i];
fft(fw,K,1);
for(int i=0;i<(K>>1);++i) fw[i]=fw[i+(K>>1)];
cp(fw+(K>>1),0,K>>1); fft(fw,K,0);
for(int i=0;i<K;++i) fw[i]=fw[i]*fh[i];
fft(fw,K,1);
for(int i=0;i<(K>>1);++i) h[i+(K>>1)]=-fw[i];
cp(gh,fg,K); pt-=K+K;
}
pt-=K+K+(K>>1);
}
void gsqrt(mi*f,mi*g,int n) {
int s=getK(n);
mi *mf=alc(s,1),*mg=alc(s),*mh=alc(s);
cp(mf,f,n); gsqrt_K(mf,mg,mh,s,0);
cp(g,mg,n); pt-=s+s+s;
}
void gexp_K(mi*f,mi*g,mi*h,int K,bool ch=1) {
if(K==1) {
g[0]=h[0]=1;
return;
}
gexp_K(f,g,h,K>>1);
mi*gg=alc(K>>1),*hh=alc(K>>1),*fh=0,
*dg=alc(K>>1),*t1=alc(K,1),*t2=alc(K,1);
dg[(K>>1)-1]=0;
for(int i=0;i+1<(K>>1);++i)
dg[i]=g[i+1]*(i+1);
cp(gg,g,K>>1); mi c=0;
for(int i=0;i<(K>>1);++i)
c=c+dg[i]*h[((K>>1)-1)-i];
if(!ch)
cp(hh,h,K>>1), fft(hh,K>>1,0);
else {
fh=alc(K,1); cp(fh,h,(K>>1)); fft(fh,K,0);
for(int i=0;i<K;i+=2) hh[i>>1]=fh[i];
}
fft(gg,K>>1,0); fft(dg,K>>1,0);
for(int i=0;i<(K>>1);++i) gg[i]=gg[i]*hh[i];
fft(gg,K>>1,1);
for(int i=0;i<(K>>1);++i)
t1[i+(K>>1)]=(i==0)-gg[i];
for(int i=0;i+1<(K>>1);++i)
t2[i]=f[i+1]*(i+1);
fft(t1,K,0); fft(t2,K,0);
for(int i=0;i<K;++i) t1[i]=t1[i]*t2[i];
fft(t1,K,1);
for(int i=0;i<(K>>1);++i) t1[i]=0;
for(int i=0;i+1<K;++i)
t1[i]=t1[i]-f[i+1]*(i+1);
for(int i=0;i<(K>>1);++i) dg[i]=dg[i]*hh[i];
fft(dg,K>>1,1); mi r;
for(int i=0;i<(K>>1);++i)
r=(i+1==(K>>1))?c:(f[i+1]*(i+1)),
t1[i]=t1[i]+r,t1[i+(K>>1)]=t1[i+(K>>1)]+dg[i]-r;
t2[0]=0;
for(int i=0;i+1<K;++i)
t2[i+1]=t1[i]*rfac[i+1]*fac[i];
cp(t1,g,K>>1); cp(t1+(K>>1),0,K>>1);
fft(t1,K,0); fft(t2,K,0);
for(int i=0;i<K;++i) t1[i]=t1[i]*t2[i];
fft(t1,K,1);
for(int i=(K>>1);i<K;++i)
g[i]=-t1[i];
pt-=K*2+(K>>1)*3;
if(ch) {
mi *fg=alc(K),*fw=alc(K);
cp(fg,g,K); fft(fg,K,0);
for(int i=0;i<K;++i) fw[i]=fg[i]*fh[i];
fft(fw,K,1);
for(int i=0;i<(K>>1);++i) fw[i]=fw[i+(K>>1)];
cp(fw+(K>>1),0,K>>1); fft(fw,K,0);
for(int i=0;i<K;++i) fw[i]=fw[i]*fh[i];
fft(fw,K,1);
for(int i=0;i<(K>>1);++i) h[i+(K>>1)]=-fw[i];
pt-=K+K+K;
}
}
void gexp(mi*f,mi*g,int n) {
int s=getK(n);
mi *mf=alc(s,1),*mg=alc(s),*mh=alc(s);
cp(mf,f,n); gexp_K(mf,mg,mh,s,0);
cp(g,mg,n); pt-=s+s+s;
}
//+ mod_sqrt
namespace QR{
typedef pair<ll,ll> pll; ll pll_s;
inline pll mul(pll a,pll b,ll p){
pll ans;ans.fi=a.fi*b.fi%p+a.se*b.se%p*pll_s%p;
ans.se=a.fi*b.se%p+a.se*b.fi%p;ans.fi%=p; ans.se%=p;return ans;}
pll qp(pll a,ll b,ll c) {pll ans(1,0);while(b) {if(b&1) ans=mul(ans,a,c);
a=mul(a,a,c); b>>=1;}return ans;}ll qp(ll a,ll b,ll c) {
ll ans=1;while(b) {if(b&1) ans=ans*a%c;a=a*a%c; b>>=1;}
return ans;}int mod_sqrt(ll a,ll p=MOD) {if(!a) return 0;
if(p==2) return 1;ll w,q;while(1) {w=rand()%p; q=w*w-a;q=(q%p+p)%p;
if(qp(q,(p-1)/2,p)!=1)break;}pll_s=q;pll rst=qp(pll(w,1),(p+1)/2,p);
ll ans=(rst.fi%p+p)%p;return min(ans,p-ans);}
}using QR::mod_sqrt;
//+ poly
#include <functional>
int default_shrink=-1; //mod x^n
struct poly {
vector<mi> coeff;
int shrink_len;
void rev() {
fit_shrink();
reverse(coeff.begin(),coeff.end());
}
void insert(mi x) {
coeff.insert(coeff.begin(),x); shrink();
}
mi& operator [] (int x) {
if((x<0)||(shrink_len!=-1&&x>=shrink_len))
throw out_of_range("invalid offset");
if((int)coeff.size()<x+1) coeff.resize(x+1);
return coeff[x];
}
mi operator [] (int x) const {
if((x<0)||(shrink_len!=-1&&x>=shrink_len))
throw out_of_range("invalid offset");
if((int)coeff.size()<x+1) return mi(0);
return coeff[x];
}
mi get(int x) const {
if((x<0)||(shrink_len!=-1&&x>=shrink_len))
return 0;
if((int)coeff.size()<x+1) return mi(0);
return coeff[x];
}
explicit poly(int shrink_len_=default_shrink):
shrink_len(shrink_len_){
}
poly(vector<mi> coeff_,int shrink_len_=default_shrink):
coeff(coeff_),shrink_len(shrink_len_){
this->shrink();
}
poly(vector<int> coeff_,int shrink_len_=default_shrink):
shrink_len(shrink_len_){
this->coeff.resize(coeff_.size());
for(int i=0;i<(int)coeff.size();++i) this->coeff[i]=coeff_[i];
this->shrink();
}
void clean_maybe() {
if(is_poly())
while(coeff.size()&&coeff.back()==0)
coeff.pop_back();
}
void clean() {
assert(is_poly());
clean_maybe();
}
void fit_shrink() {
assert(is_series());
coeff.resize(shrink_len);
}
void set_shrink(int shrink_len_=default_shrink) {
this->shrink_len=shrink_len_; this->shrink();
}
void dump(char e=0,bool g=1,int l=9) const {
auto format=[&](mi num) {
return g?pretty_guess(num):to_string(num);
};
int u=(int)coeff.size()-1;
while(u>=0&&coeff[u]==0) --u;
if(u<0) {
printf("{}");
}
else {
for(int j=0;j<=u&&j<=l;++j)
printf("%c%s","{,"[j!=0],format(coeff[j]).c_str());
if(u>l)
printf("...%s(x^%d)",format(coeff[u]).c_str(),u);
printf("}");
}
if(shrink_len==-1)
printf(" (poly)");
else printf(" (mod x^%d)",shrink_len);
if(e) putchar(e);
}
const mi* coeff_ptr() const {
if(!coeff.size()) return 0;
return coeff.data();
}
mi* coeff_ptr() {
if(!coeff.size()) return 0;
return coeff.data();
}
int size() const {
return coeff.size();
}
void reserve(int l) {
if(shrink_len!=-1)
l=min(l,shrink_len);
if(l>(int)coeff.size())
coeff.resize(l);
}
void print_shrink(char e) {
fit_shrink();
for(int i=0;i<shrink_len;++i) {
if(i) printf(" ");
printf("%d",(int)coeff[i]);
}
if(e) printf("%c",e);
}
void print_len(int s,char e) {
for(int i=0;i<s;++i) {
if(i) printf(" ");
printf("%d",(int)get(i));
}
if(e) printf("%c",e);
}
void shrink() {
if(shrink_len!=-1&&(int)coeff.size()>shrink_len)
coeff.resize(shrink_len);
}
bool is_poly() const {return shrink_len==-1;}
bool is_series() const {return shrink_len!=-1;}
mi eval(mi x) {
assert(is_poly()); mi w=0;
for(int i=size()-1;i>=0;--i)
w=w*x+coeff[i];
return w;
}
};
poly polyi(mi x) {
return poly(vector<mi>{x},-1);
}
poly operator"" _p(unsigned long long int x) {
return poly(vector<mi>{int(x%MOD)},-1);
}
poly operator"" _p(const char *str,std::size_t len) {
poly ans(-1); int sgn=1,phase=0,coeff=0,touch=0;
ll cnum=0;
auto clean=[&]() {
if(phase==-1) ans[1]+=sgn*coeff;
else if(phase==0) ans[0]+=sgn*(int)cnum;
else if(phase==1) ans[cnum]+=sgn*coeff;
else assert(0);
phase=cnum=touch=0;
};
for(int i=0;i<(int)len;++i) {
if(str[i]=='+') clean(),sgn=1;
else if(str[i]=='-') clean(),sgn=-1;
else if(isdigit(str[i])) {
assert(phase==0||phase==1);
if(phase==0) touch=1,cnum=(cnum*10LL+str[i]-48)%MOD;
else cnum=cnum*10LL+str[i]-48,assert(cnum<1e8);
}
else if(str[i]=='x') {
assert(str[i+1]=='^'||str[i+1]=='+'||str[i+1]=='-'||str[i+1]==0);
phase=-1; coeff=touch?cnum:1; cnum=0;
}
else if(str[i]=='^') {
assert(phase==-1); phase=1;
}
}
clean();
return ans;
}
//+ poly ops
void share_shrink(poly&a,poly&b) {
int l=max(a.shrink_len,b.shrink_len);
a.set_shrink(l);b.set_shrink(l);
}
poly ginv(poly p) {
p.fit_shrink();
ginv(p.coeff_ptr(),p.coeff_ptr(),p.shrink_len);
return p;
}
poly gln(poly p) {
p.fit_shrink();
gln(p.coeff_ptr(),p.coeff_ptr(),p.shrink_len);
return p;
}
poly gsqrt(poly p,mi f0=mi(1)) {
p.fit_shrink(); sqrt_f0=f0;
gsqrt(p.coeff_ptr(),p.coeff_ptr(),p.shrink_len);
return p;
}
poly gexp(poly p) {
p.fit_shrink();
gexp(p.coeff_ptr(),p.coeff_ptr(),p.shrink_len);
return p;
}
int merge_shrink(int s1,int s2) {
if(s1==-1) return s2;
if(s2==-1) return s1;
assert(s1==s2); //usually s1=s2
return min(s1,s2);
}
poly operator + (const poly& a,const poly& b) {
poly c(merge_shrink(a.shrink_len,b.shrink_len));
c.reserve(max(a.size(),b.size()));
for(int i=0;i<c.size();++i) c[i]=a[i]+b[i];
return c;
}
poly operator - (const poly& a,const poly& b) {
poly c(merge_shrink(a.shrink_len,b.shrink_len));
c.reserve(max(a.size(),b.size()));
for(int i=0;i<c.size();++i) c[i]=a[i]-b[i];
return c;
}
poly operator - (poly a) {
for(auto&s:a.coeff) s=-s; return a;
}
poly operator * (mi v,poly a) {
for(auto&t:a.coeff) t=t*v;
return a;
}
poly operator * (poly a,mi v) {
for(auto&t:a.coeff) t=t*v;
return a;
}
poly operator + (poly a,mi b) {
a.reserve(1);
if(a.size()) a[0]+=b;
return a;
}
poly operator - (poly a,mi b) {
a.reserve(1);
if(a.size()) a[0]-=b;
return a;
}
poly operator * (const poly& a,const poly& b) {
if(!a.size()) return a;
if(!b.size()) return b;
poly c(merge_shrink(a.shrink_len,b.shrink_len));
c.reserve(a.size()+b.size()-1);
int as=min(a.size(),c.size()),
bs=min(b.size(),c.size());
int K=getK(as+bs-1);
mi*da=alc(K,1),*db=alc(K,1);
for(int i=0;i<as;++i) da[i]=a[i];
for(int i=0;i<bs;++i) db[i]=b[i];
fft(da,K,0,0); fft(db,K,0,0);
for(int i=0;i<K;++i) da[i]=da[i]*db[i];
fft(da,K,1,0);
for(int i=0;i<c.size();++i) c[i]=da[i];
pt-=K*2;
return c;
}
pair<poly,poly> gdiv(poly a,poly b) { //(quotient, remainder)
assert(a.is_poly()&&b.is_poly());
int n=a.size(),m=b.size(); assert(m>0);
if(n<m)
return make_pair(poly(-1),a);
poly d(-1),r(-1); d.reserve(n-m+1); r.reserve(m-1);
gdiv(a.coeff_ptr(),b.coeff_ptr(),d.coeff_ptr(),r.coeff_ptr(),n,m);
return make_pair(d,r);
}
poly operator / (poly a,poly b) {
assert(a.is_poly()&&b.is_poly());
int n=a.size(),m=b.size(); assert(m>0);
if(n<m) return poly(-1);
poly d(-1); d.reserve(n-m+1);
gdiv(a.coeff_ptr(),b.coeff_ptr(),d.coeff_ptr(),n,m);
return d;
}
poly gint(poly a) { //shrink actually changes
a.reserve(a.size()+1);
for(int i=a.size()-1;i>=1;--i)
a[i]=a[i-1]*rfac[i]*fac[i-1];
if(a.size()) a[0]=0;
return a;
}
poly gde(poly a) { //shrink actually changes
if(!a.size()) return a;
for(int i=1;i<a.size();++i)
a[i-1]=a[i]*i;
a[a.size()-1]=0;
a.clean_maybe();
return a;
}
poly gpow(poly p,string k) {
int u=p.shrink_len,x=0;
p.fit_shrink();
while(x<u&&p[x]==0) ++x;
double kd=0; mi m0=0; ll m1=0;
for(char c:k) {
kd=kd*10+c-48;
m0=m0*10+int(c-48);
m1=(m1*10+int(c-48))%(MOD-1);
}
if(x==u||x*kd>=u*2) return poly(u);
p.coeff.erase(p.coeff.begin(),p.coeff.begin()+x);
mi v=p[0],s=qp(v,m1),iv=inv(v);
for(mi&w:p.coeff) w=w*iv;
p=gexp(m0*gln(p));
for(mi&w:p.coeff) w=w*s;
p.coeff.insert(p.coeff.begin(),x*m1,mi(0));
p.fit_shrink(); return p;
}
poly gpow(poly p,ll k) {
return gpow(p,to_string(k));
}
poly prod_recurse(poly*a,int n) {
if(n==1) return *a; int m=n>>1;
return prod_recurse(a,m)*prod_recurse(a+m,n-m);
}
poly prod(vector<poly> p) {
if(!p.size()) return poly(-1);
sort(p.begin(),p.end(),[&](const poly&a,const poly&b) {
return a.size()<b.size();
});
return prod_recurse(p.data(),p.size());
}
poly gcorner(poly a,vector<mi> b) {
a.reserve(b.size());
for(int i=0;i<a.size()&&i<(int)b.size();++i)
a[i]=b[i];
return a;
}
poly gshl(poly a,int b) {
a.coeff.insert(a.coeff.begin(),b,mi(0));
a.shrink(); return a;
}
poly gshr(poly a,int b) {
if(a.size()<b) a.coeff.clear();
else a.coeff.erase(a.coeff.begin(),a.coeff.begin()+b);
a.shrink(); return a;
}
poly gamp(const poly& a,int u) { //A(x)=a(x^u)
assert(a.is_series()&&u>=1); poly b(a.shrink_len);
for(int i=0;i*u<a.shrink_len;++i) b[i*u]=a[i]; return b;
}
mi C(int n1,int m1){
if(m1<0||m1>n1)return 0;
return fac[n1]*rfac[m1]*rfac[n1-m1];
}
poly gmov(poly p,mi c){
// p.print_shrink('\n');
assert(p.shrink_len!=-1);
int m=p.shrink_len-1;
for(int i=0;i<=m;i++)p[i]=p[i]*fac[i];
poly p2=poly(m+1);for(int i=0;i<=m;i++)p2[i]=rfac[i]*qp(c,i);
for(int i=0;i*2<m;i++)swap(p[i],p[m-i]);
// p.print_shrink('\n');
p=p*p2;
for(int i=0;i*2<m;i++)swap(p[i],p[m-i]);
for(int i=0;i<=m;i++)p[i]=p[i]*rfac[i];
return p;
}
struct frac{
poly pa=poly(-1),pc=poly(-1);
friend frac operator+(frac f1,frac f2){
frac ret;
ret.pa=f1.pa*f2.pc+f1.pc*f2.pa;ret.pc=f1.pc*f2.pc;
// ret.pa.print_len(10,'\n');
return ret;
}
}res[209376];
poly calc(frac fr,int m){
poly p1=fr.pa,p2=fr.pc;
//p1.print_shrink('\n');
p1.set_shrink(m+1);p2.set_shrink(m+1);
// printf("A:");p1.print_shrink('\n');p2.print_shrink('\n');
return p1*ginv(p2);
}
frac divsum(frac *des,int l,int r){
if(r<=l)return des[l];
int mid=(l+r)>>1;
return divsum(des,l,mid)+divsum(des,mid+1,r);
}
void divcal(poly &des,poly &ref1,poly &ref2,int l,int r){
if(l==r){
des[l]=des[l]/(fac[l]-ref1[l])+fac[l]/(fac[l]-ref1[l]);
return;
}
int mid=(l+r)>>1;
divcal(des,ref1,ref2,l,mid);
poly rp1=poly(r-l+1),rp2=poly(r-l+1);
for(int i=l;i<=mid;i++)rp1[i-l]=des[i]*ref1[i];
for(int i=l;i<=r;i++)rp2[i-l]=ref2[i-l];
rp1=rp1*rp2;
for(int i=mid+1;i<=r;i++)des[i]+=rp1[i-l];
//printf("%d %d\n",l,r);
//rp1.print_shrink('\n');
divcal(des,ref1,ref2,mid+1,r);
}
int t,n,m,a[205416];
int main()
{
cin>>n;
poly p0=poly(n+1);
for(int i=0;i<=n;i++)p0[i]=fac[i];
poly p1=(p0-1)*ginv(p0);
//p1.print_shrink('\n');
poly p2=p0*p0;p2[0]=0;
poly ans=poly(n+1);
ans[0]=0;ans[1]=0;
divcal(ans,p1,p2,1,n);
//ans.print_shrink('\n');
long long sum=0;
int las=0;
mi pri=0;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
if(sum==((long long)i)*((long long)(i+1))/2){
pri+=ans[i-las];
las=i;
}
}
cout<<pri;
}
这程序好像有点Bug,我给组数据试试?
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 158ms
memory: 229880kb
input:
5 2 1 5 3 4
output:
332748123
result:
ok 1 number(s): "332748123"
Test #2:
score: 0
Accepted
time: 162ms
memory: 230988kb
input:
10 4 2 3 1 6 5 9 7 10 8
output:
453747445
result:
ok 1 number(s): "453747445"
Test #3:
score: 0
Accepted
time: 159ms
memory: 229140kb
input:
1 1
output:
0
result:
ok 1 number(s): "0"
Test #4:
score: 0
Accepted
time: 159ms
memory: 229488kb
input:
100 76 73 11 3 60 77 27 93 12 86 40 66 36 2 49 65 17 39 4 20 5 72 67 61 6 35 43 64 58 96 24 68 88 99 94 81 52 13 71 45 32 15 78 85 46 44 55 95 21 53 9 48 26 47 75 33 34 14 70 90 100 62 23 29 22 41 63 84 59 80 38 56 69 25 92 31 50 74 51 87 30 19 91 28 42 89 82 83 97 16 37 54 1 98 10 18 8 57 7 79
output:
508737759
result:
ok 1 number(s): "508737759"
Test #5:
score: 0
Accepted
time: 162ms
memory: 228952kb
input:
1000 644 749 436 202 582 786 943 410 790 963 151 352 625 18 731 435 184 758 614 897 257 917 910 402 589 825 134 380 832 547 77 9 956 229 448 568 769 163 255 364 363 868 148 168 407 663 928 886 450 854 546 994 902 517 793 700 677 936 799 958 475 558 350 650 135 728 768 118 789 231 322 455 221 438 317...
output:
679753239
result:
ok 1 number(s): "679753239"
Test #6:
score: 0
Accepted
time: 407ms
memory: 236440kb
input:
100000 73995 97531 73688 16747 13958 91688 67443 27446 19321 76786 84775 67782 50687 46881 24663 30944 52408 88244 25123 73060 26112 21434 89167 40474 48955 7460 39368 85932 58361 5973 55773 52839 31407 22934 66635 51540 12512 2579 16556 74872 88172 39911 20556 99234 48914 97168 60821 47627 45539 20...
output:
890612070
result:
ok 1 number(s): "890612070"
Test #7:
score: 0
Accepted
time: 410ms
memory: 229736kb
input:
100000 75639 75018 56529 53744 97883 13810 42035 21043 11904 37776 66333 31553 82625 47621 18443 36067 36565 17637 37034 21085 10887 40242 76683 90743 58636 53510 13083 67050 36592 26238 24625 77890 36480 12131 9739 54629 22636 91688 93885 13773 59255 5228 32255 91075 95398 20112 6931 92388 78047 55...
output:
890612070
result:
ok 1 number(s): "890612070"
Test #8:
score: 0
Accepted
time: 407ms
memory: 237164kb
input:
100000 6365 78742 79932 37888 33087 27426 32649 32057 47518 99279 43260 73945 55233 82364 94282 40764 46484 47000 68011 87455 18440 38672 77423 91903 52861 5406 36397 57738 97560 89551 66432 6075 53328 50420 46057 49025 2212 5425 22322 83098 73958 18694 54172 30402 9877 47903 74697 32095 26271 46989...
output:
890612070
result:
ok 1 number(s): "890612070"
Test #9:
score: 0
Accepted
time: 159ms
memory: 223200kb
input:
2 2 1
output:
2
result:
ok 1 number(s): "2"
Test #10:
score: 0
Accepted
time: 159ms
memory: 229232kb
input:
3 3 1 2
output:
332748121
result:
ok 1 number(s): "332748121"
Test #11:
score: 0
Accepted
time: 158ms
memory: 229068kb
input:
4 2 4 1 3
output:
725995898
result:
ok 1 number(s): "725995898"
Test #12:
score: 0
Accepted
time: 159ms
memory: 219972kb
input:
5 4 1 3 5 2
output:
181498980
result:
ok 1 number(s): "181498980"
Test #13:
score: 0
Accepted
time: 159ms
memory: 218564kb
input:
6 5 3 2 1 6 4
output:
231603911
result:
ok 1 number(s): "231603911"
Test #14:
score: 0
Accepted
time: 156ms
memory: 228940kb
input:
7 5 1 4 2 7 3 6
output:
962358036
result:
ok 1 number(s): "962358036"
Test #15:
score: 0
Accepted
time: 156ms
memory: 229068kb
input:
8 4 2 8 7 3 1 6 5
output:
612851697
result:
ok 1 number(s): "612851697"
Test #16:
score: 0
Accepted
time: 155ms
memory: 230308kb
input:
9 2 9 3 6 1 5 4 8 7
output:
375472763
result:
ok 1 number(s): "375472763"
Test #17:
score: 0
Accepted
time: 161ms
memory: 229528kb
input:
10 10 4 5 1 8 9 2 6 3 7
output:
352546511
result:
ok 1 number(s): "352546511"
Test #18:
score: 0
Accepted
time: 439ms
memory: 225816kb
input:
100000 1 2 3 4 6 5 7 9 10 8 12 11 13 14 15 16 17 18 19 22 24 21 25 20 23 27 26 29 28 30 33 31 32 34 35 39 36 37 38 40 42 41 43 44 46 45 48 47 49 50 51 52 53 54 55 56 57 59 58 61 60 62 63 64 65 66 67 69 68 70 72 71 74 73 75 76 78 79 77 80 82 81 83 84 85 86 87 88 90 89 91 92 93 94 95 98 96 97 100 99 1...
output:
210320684
result:
ok 1 number(s): "210320684"
Test #19:
score: 0
Accepted
time: 408ms
memory: 244172kb
input:
100000 1 2 3 4 5 6 7 8 11 9 10 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 36 35 37 38 40 39 41 43 42 45 44 46 47 50 49 48 51 52 53 54 56 55 57 59 58 60 61 62 63 65 64 68 66 67 69 71 70 73 72 75 74 76 78 77 81 79 80 82 83 84 85 86 87 88 89 91 90 92 93 94 95 97 96 99 98 101 1...
output:
270035219
result:
ok 1 number(s): "270035219"
Test #20:
score: 0
Accepted
time: 404ms
memory: 236840kb
input:
100000 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 60 59 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 78 77 79 80 81 82 83 84 85 86 87 88 89 91 90 92 93 95 94 96 97 98 99 100 1...
output:
605008306
result:
ok 1 number(s): "605008306"
Test #21:
score: 0
Accepted
time: 410ms
memory: 227088kb
input:
100000 2 1 4 5 3 7 6 9 8 12 11 10 14 13 15 17 18 16 19 21 20 23 24 22 25 26 27 28 30 29 32 31 34 33 36 37 35 38 39 41 40 43 42 46 44 48 45 47 50 49 51 52 53 54 58 57 55 56 62 60 59 61 67 68 69 65 70 66 63 64 71 72 73 75 74 77 76 79 78 82 81 83 80 86 84 85 87 88 89 93 90 91 92 96 94 95 97 99 98 101 1...
output:
495537170
result:
ok 1 number(s): "495537170"
Test #22:
score: 0
Accepted
time: 407ms
memory: 244388kb
input:
100000 63073 28667 90975 30352 3761 94190 79972 43048 21778 33653 36197 15091 608 19719 989 52387 77322 60994 47624 43439 23816 67364 99594 78540 14592 23284 76709 93993 91131 92333 87166 76515 65187 93200 55352 73418 5417 62724 89224 44808 30562 77028 86252 62548 60089 72547 31563 68303 9267 37119 ...
output:
890612070
result:
ok 1 number(s): "890612070"
Test #23:
score: 0
Accepted
time: 412ms
memory: 227820kb
input:
100000 40205 6086 18833 72928 8675 2421 39538 10358 33411 19062 21955 49175 25071 356 53723 1249 39168 4166 41373 71509 7236 19815 51707 28958 19596 12000 34436 64228 24654 13516 37785 58526 64106 67407 22334 38939 8020 50688 75295 37521 32185 64781 4779 34223 22027 69356 44383 22618 23734 15468 270...
output:
88556225
result:
ok 1 number(s): "88556225"
Test #24:
score: 0
Accepted
time: 409ms
memory: 238028kb
input:
100000 13177 13025 19647 20671 21372 25297 23161 25709 9980 18962 26049 259 15667 5396 19714 25946 7421 19163 8310 5203 7356 22748 21994 16406 8927 4437 13123 11514 25572 20363 2776 8988 6884 10095 13026 16181 3703 321 5459 19285 17305 25129 13822 13685 23863 5389 9401 2056 22066 13275 13133 2023 90...
output:
249803513
result:
ok 1 number(s): "249803513"
Test #25:
score: 0
Accepted
time: 404ms
memory: 244168kb
input:
100000 118 359 351 462 171 279 312 125 315 362 249 425 194 356 226 436 204 122 87 331 398 127 73 278 384 262 377 299 129 242 264 212 215 75 82 392 36 417 407 382 102 210 4 21 130 136 361 461 410 432 319 420 427 292 443 180 261 197 63 370 459 92 151 214 454 158 396 74 376 435 287 386 199 437 348 441 ...
output:
224837018
result:
ok 1 number(s): "224837018"
Test #26:
score: 0
Accepted
time: 407ms
memory: 226380kb
input:
100000 16 60 89 57 102 10 94 39 1 62 49 76 61 82 105 17 42 63 9 47 69 7 31 87 50 21 71 43 3 114 54 25 32 93 115 81 36 118 79 34 58 88 29 91 5 56 66 117 80 104 83 55 108 75 95 18 112 101 113 100 41 96 6 14 35 107 84 85 38 45 33 103 59 22 28 68 8 11 26 98 110 116 2 78 97 12 86 46 111 53 92 15 65 77 44...
output:
831156714
result:
ok 1 number(s): "831156714"
Test #27:
score: 0
Accepted
time: 411ms
memory: 236012kb
input:
100000 10 22 8 13 20 3 9 14 11 12 15 7 19 16 21 17 23 18 1 4 2 6 5 25 24 29 27 28 26 31 30 44 34 32 38 37 41 43 36 39 40 42 46 33 35 45 48 47 53 49 50 51 52 54 57 58 61 60 56 64 65 55 66 63 59 62 68 67 72 70 69 71 77 76 80 74 75 73 81 78 79 82 85 84 83 88 89 86 87 102 106 103 98 93 100 94 96 105 101...
output:
374593697
result:
ok 1 number(s): "374593697"
Test #28:
score: 0
Accepted
time: 415ms
memory: 239568kb
input:
100000 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 1...
output:
0
result:
ok 1 number(s): "0"
Test #29:
score: 0
Accepted
time: 411ms
memory: 244168kb
input:
100000 40 48 75 84 93 34 1 12 16 8 22 96 68 55 74 70 59 52 24 19 78 2 63 43 39 18 54 32 89 42 57 47 6 72 28 35 9 95 20 29 67 64 37 71 38 41 46 77 61 88 3 5 87 80 51 65 17 86 82 90 97 98 73 36 44 62 60 49 25 27 83 13 10 11 58 14 66 15 4 7 56 30 33 81 99 31 23 76 85 21 91 92 45 26 50 94 69 79 53 135 1...
output:
577674591
result:
ok 1 number(s): "577674591"
Test #30:
score: 0
Accepted
time: 414ms
memory: 237120kb
input:
100000 3 1 2 5 6 4 10 9 8 7 11 19 17 14 16 13 12 15 18 24 20 22 21 25 23 27 26 28 30 29 31 36 34 35 33 37 32 39 40 38 43 45 41 42 46 44 48 47 50 49 51 53 52 56 54 58 55 59 57 60 62 64 61 63 67 66 65 69 72 68 75 73 74 71 70 98 78 102 77 93 86 92 85 96 79 99 84 83 81 91 87 97 89 94 100 82 103 80 95 10...
output:
516708075
result:
ok 1 number(s): "516708075"
Extra Test:
score: 0
Extra Test Passed