QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#664269 | #9493. 路径计数 | ucup-team1004 | 18 | 8608ms | 647500kb | C++17 | 11.7kb | 2024-10-21 19:56:20 | 2024-10-21 19:56:20 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#ifdef DEBUG
#include"debug.h"
#else
#define debug(...) void()
#endif
#define all(x) (x).begin(),(x).end()
template<class T>
auto ary(T *a,int l,int r){
return vector<T>{a+l,a+1+r};
}
using ll=long long;
using ull=unsigned long long;
int mod=998244353,base;
using comp=complex<double>;
struct fastmod {
typedef unsigned long long u64;
typedef __uint128_t u128;
int m;
u64 b;
fastmod(int m) : m(m), b(((u128)1 << 64) / m) {}
int reduce(u64 a) {
u64 q = ((u128)a * b) >> 64;
int r = a - q * m;
return r < m ? r : r - m;
}
} Fast(2);
namespace Poly{
const double pi=acos(-1);
const int N=1<<20;
int lim,rev[N];
comp a0[N],a1[N],b0[N],b1[N],c0[N],c1[N],c2[N],pw[N];
void Init(){
for(int len=1;len<N;len<<=1){
for(int i=0;i<len;i++){
pw[len|i]=comp(cos(pi/len*i),sin(pi/len*i));
}
}
}
void init(int n){
for(lim=1;lim<n;lim<<=1);
for(int i=1;i<lim;i++)rev[i]=rev[i>>1]>>1|(i&1?lim>>1:0);
}
namespace Public{
using poly=vector<int>;
void FFT(comp *a,int op){
for(int i=0;i<lim;i++)if(rev[i]<i)swap(a[rev[i]],a[i]);
for(int len=1;len<lim;len<<=1){
for(int i=0;i<lim;i+=len<<1){
for(int j=0;j<len;j++){
comp x=a[i|j],y=a[i|j|len]*pw[len|j];
a[i|j]=x+y,a[i|j|len]=x-y;
}
}
}
if(op<0){
reverse(a+1,a+lim);
for(int i=0;i<lim;i++)a[i]/=lim;
}
}
void DFT(const poly &a,comp *a0,comp *a1){
int n=a.size();
for(int i=0;i<n;i++)a0[i]=comp(a[i]%base,a[i]/base);
fill(a0+n,a0+lim,comp(0,0));
FFT(a0,1);
copy(a0,a0+lim,a1);
reverse(a1+1,a1+lim);
for(int i=0;i<lim;i++)a1[i]=conj(a1[i]);
for(int i=0;i<lim;i++){
comp p=a0[i],q=a1[i];
a0[i]=(p+q)*comp(0.5,0);
a1[i]=(q-p)*comp(0,0.5);
}
}
poly iDFT(comp *c0,comp *c1){
FFT(c0,-1),FFT(c1,-1);
auto calc=[&](double x)->ll {
if(x>0)return Fast.reduce(ll(x+0.5));
else{
int res=Fast.reduce(-ll(x-0.5));
return res?mod-res:0;
}
};
poly c(lim);
for(int i=0;i<lim;i++){
c[i]=Fast.reduce(calc(imag(c1[i]))*base*base+calc(real(c0[i]))*base+calc(real(c1[i])));
}
return c;
}
pair<poly,poly> iDFT(comp *c0,comp *c1,comp *d0,comp *d1){
for(int i=0;i<lim;i++)c0[i]+=comp(0,1)*d0[i];
FFT(c0,-1),FFT(c1,-1),FFT(d1,-1);
auto calc=[&](double x)->ll {
if(x>0)return Fast.reduce(ll(x+0.5));
else{
int res=Fast.reduce(-ll(x-0.5));
return res?mod-res:0;
}
};
poly c(lim),d(lim);
for(int i=0;i<lim;i++){
c[i]=Fast.reduce(calc(imag(c1[i]))*base*base+calc(real(c0[i]))*base+calc(real(c1[i])));
}
for(int i=0;i<lim;i++){
d[i]=Fast.reduce(calc(imag(d1[i]))*base*base+calc(imag(c0[i]))*base+calc(real(d1[i])));
}
return make_pair(c,d);
}
void inc(comp *a0,comp *a1,comp *b0,comp *b1,comp *c0,comp *c1){
for(int i=0;i<lim;i++){
c0[i]+=a1[i]*b0[i]+a0[i]*b1[i];
c1[i]+=a0[i]*b0[i]+comp(0,1)*a1[i]*b1[i];
}
}
poly operator * (const poly &a,const poly &b){
int n=a.size(),m=b.size(),k=n+m-1;
if(min(n,m)<=40){
poly c(k);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
c[i+j]=Fast.reduce(c[i+j]+1ll*a[i]*b[j]);
}
}
return c;
}
init(k);
DFT(a,a0,a1),DFT(b,b0,b1);
fill(c0,c0+lim,comp(0,0));
fill(c1,c1+lim,comp(0,0));
inc(a0,a1,b0,b1,c0,c1);
auto c=iDFT(c0,c1);
return c.resize(k),c;
}
poly& operator *= (poly &a,const poly &b){
return a=a*b;
}
poly& operator += (poly &a,const poly &b){
int n=a.size(),m=b.size();
if(n<m)a.resize(m);
for(int i=0;i<m;i++)(a[i]+=b[i])>=mod&&(a[i]-=mod);
return a;
}
poly operator + (const poly &a,const poly &b){
poly c(a);
return c+=b;
}
poly& operator -= (poly &a,const poly &b){
int n=a.size(),m=b.size();
if(n<m)a.resize(m);
for(int i=0;i<m;i++)(a[i]-=b[i])<0&&(a[i]+=mod);
return a;
}
poly operator - (const poly &a,const poly &b){
poly c(a);
return c-=b;
}
poly operator - (const poly &a){
return poly()-a;
}
poly& operator *= (poly &a,const int &b){
for(int &x:a)x=Fast.reduce(1ll*x*b);
return a;
}
poly operator * (const poly &a,const int &b){
poly c(a);
return c*=b;
}
poly& operator %= (poly &a,const int &b){
if(a.size()>b)a.resize(b);
return a;
}
poly operator % (const poly &a,const int &b){
poly c(a);
return c%=b;
}
poly inv(poly a,int n=-1){
if(n==-1)n=a.size();
if(n==1)return poly(1,1);
int m=(n+1)/2;
auto b=inv(a%m,m);
init(n+m-1);
static comp a0[N],a1[N],b0[N],b1[N],c0[N],c1[N];
DFT(a,a0,a1),DFT(b,b0,b1);
fill(c0,c0+lim,comp(0,0));
fill(c1,c1+lim,comp(0,0));
inc(a0,a1,b0,b1,c0,c1);
a=iDFT(c0,c1),a.resize(n);
DFT(a,a0,a1);
fill(c0,c0+lim,comp(0,0));
fill(c1,c1+lim,comp(0,0));
inc(a0,a1,b0,b1,c0,c1);
a=iDFT(c0,c1),a.resize(n);
return b*2-a;
}
}
}
using namespace Poly::Public;
const int N=2e5+10,M=1<<19|10;
int sid,n,m,a[N],b[N],c[N],d[N],e[N],f[N];
using vec=array<poly,2>;
using matrix=array<vec,2>;
#ifdef DEBUG
ostream& operator << (ostream &out,vec a){
out<<'[';
for(auto x:a)out<<x<<',';
return out<<']';
}
ostream& operator << (ostream &out,matrix a){
out<<'[';
for(auto x:a)out<<x<<',';
return out<<']';
}
#endif
matrix operator * (matrix a,matrix b){
int n=0;
for(int i:{0,1})for(int j:{0,1})for(int k:{0,1}){
n=max(n,(int)a[i][j].size()+(int)b[j][k].size()-1);
}
matrix c;
if(n<=50){
for(int i:{0,1})for(int j:{0,1})for(int k:{0,1}){
if(!a[i][j].empty()&&!b[j][k].empty())c[i][k]+=a[i][j]*b[j][k];
}
return c;
}
Poly::init(n),n=Poly::lim;
static comp a0[2][2][M],a1[2][2][M];
static comp b0[2][2][M],b1[2][2][M];
static comp c0[M],c1[M];
for(int i:{0,1})for(int j:{0,1}){
DFT(a[i][j],a0[i][j],a1[i][j]);
DFT(b[i][j],b0[i][j],b1[i][j]);
}
for(int i:{0,1})for(int j:{0,1}){
fill(c0,c0+n,comp(0,0));
fill(c1,c1+n,comp(0,0));
for(int k:{0,1})inc(a0[i][k],a1[i][k],b0[k][j],b1[k][j],c0,c1);
c[i][j]=iDFT(c0,c1);
for(;!c[i][j].empty()&&!c[i][j].back();c[i][j].pop_back());
}
return c;
}
matrix mul(matrix a,matrix b){
matrix c;
for(int i:{0,1})for(int j:{0,1})for(int k:{0,1}){
if(!a[i][j].empty()&&!b[j][k].empty())c[i][k]+=a[i][j]*b[j][k];
}
return c;
}
vec solve(int l,int r){
if(l==r){
// debug("solve",l,r,vec{poly{b[l],1},poly{e[l]}});
return vec{poly{b[l],1},poly{e[l]}};
}
int mid=(l+r)>>1,n=0;
auto L=solve(l,mid),R=solve(mid+1,r);
for(int i:{0,1})for(int j:{0,1})if(!i||!j){
n=max(n,(int)L[i].size()+(int)R[j].size()-1);
}
// debug("solve",l,r);
Poly::init(n),n=Poly::lim;
vec t;
static comp L0[M],L1[M];
static comp R0[2][M],R1[2][M];
static comp t0[2][M],t1[2][M];
DFT(L[0],L0,L1);
for(int i:{0,1}){
fill(t0[i],t0[i]+n,comp(0,0));
fill(t1[i],t1[i]+n,comp(0,0));
DFT(R[i],R0[i],R1[i]);
}
inc(L0,L1,R0[0],R1[0],t0[0],t1[0]);
inc(L0,L1,R0[1],R1[1],t0[1],t1[1]);
tie(t[0],t[1])=iDFT(t0[0],t1[0],t0[1],t1[1]);
for(int i:{0,1}){
for(;!t[i].empty()&&!t[i].back();t[i].pop_back());
}
t[1]+=L[1];
// debug("solve",l,r,t);
return t;
}
struct node{
matrix F;
poly G[2][3];
poly calc(int cr){
return F[0][0]*poly{(mod-cr)%mod,1}+F[0][1];
}
void mul(poly g,int k){
Poly::init(G[0][0].size()+g.size()-1);
int n=Poly::lim;
static comp g0[M],g1[M],w0[2][M],w1[2][M];
static comp G0[M],G1[M];
DFT(g,g0,g1);
for(int j:{0,1,2}){
for(int i:{0,1}){
DFT(G[i][j],G0,G1);
fill(w0[i],w0[i]+n,comp(0,0));
fill(w1[i],w1[i]+n,comp(0,0));
inc(g0,g1,G0,G1,w0[i],w1[i]);
}
tie(G[0][j],G[1][j])=iDFT(w0[0],w1[0],w0[1],w1[1]);
G[0][j].resize(k),G[1][j].resize(k);
}
}
};
void expand(poly &a,poly f,poly g,int m){
int n=a.size();
if(m<=n)return a%=m,void();
a=a*f%n*g%m;
}
const int K=400;
matrix gen(int i){
matrix cur;
cur[0][0]=poly{(mod-c[i])%mod,1};
cur[0][1]=poly{int(1ll*(mod-a[i])*d[i+1]%mod)};
cur[1][0]=poly{1};
return cur;
}
node divide(int l,int r){
int n=r-l+1;
if(r-l+1<=K){
node res;
function<matrix(int,int)>dfs=[&](int l,int r){
if(l==r)return gen(l);
int mid=(l+r)>>1;
return dfs(l,mid)*dfs(mid+1,r);
};
if(l<r)res.F=dfs(l,r-1);
else res.F[0][0]=res.F[1][1]=poly{1};
static int w[K][N];
for(int x:{0,1}){
for(int i=0;i<n;i++)fill(w[i]+l,w[i]+1+r,0);
w[0][x?r:l]=1;
for(int i=0;i+1<n;i++){
for(int j=l;j<=r;j++)w[i+1][j]=Fast.reduce(w[i+1][j]+1ll*w[i][j]*c[j]);
for(int j=l;j<r;j++)w[i+1][j+1]=Fast.reduce(w[i+1][j+1]+1ll*w[i][j]*a[j]);
for(int j=r;j>l;j--)w[i+1][j-1]=Fast.reduce(w[i+1][j-1]+1ll*w[i][j]*d[j]);
}
res.G[x][0].resize(n);
res.G[x][1].resize(n);
res.G[x][2].resize(n);
for(int i=0;i<n;i++){
res.G[x][0][i]=Fast.reduce(res.G[x][0][i]+w[i][l]);
res.G[x][1][i]=Fast.reduce(res.G[x][1][i]+w[i][r]);
for(int j=l;j<=r;j++){
res.G[x][2][i]=Fast.reduce(res.G[x][2][i]+1ll*w[i][j]*f[j]);
}
}
}
return res;
}
int mid=(l+r)>>1;
auto L=divide(l,mid-1),R=divide(mid+1,r);
auto fl=L.calc(c[mid-1]),fr=R.calc(c[r]);
reverse(all(fl)),reverse(all(fr));
auto ifl=inv(fl,n),ifr=inv(fr,n);
L.mul(fl,mid-l),R.mul(fr,r-mid);
L.mul(ifl,n),R.mul(ifr,n);
node res;
res.F=mul(L.F,gen(mid-1))*mul(gen(mid),R.F);
poly h=(poly{0,c[mid]}+
L.G[1][1]*poly{0,0,int(1ll*d[mid]*a[mid-1]%mod)}+
R.G[0][0]*poly{0,0,int(1ll*a[mid]*d[mid+1]%mod)})%n;
h=inv(poly{1}-h,n);
poly p[2],q[3];
p[0]=poly{0,a[mid-1]}*L.G[0][1]%n;
p[1]=poly{0,d[mid+1]}*R.G[1][0]%n;
q[0]=poly{0,d[mid]}*L.G[1][0]%n;
q[1]=poly{0,a[mid]}*R.G[0][1]%n;
q[2]=(poly{0,d[mid]}*L.G[1][2]+poly{0,a[mid]}*R.G[0][2]+poly{f[mid]})%n;
Poly::init(n+n-1);
int k=Poly::lim;
static comp p0[2][M],p1[2][M],h0[M],h1[M],w0[2][M],w1[2][M];
DFT(p[0],p0[0],p1[0]);
DFT(p[1],p0[1],p1[1]);
DFT(h,h0,h1);
fill(w0[0],w0[0]+k,comp(0,0));
fill(w1[0],w1[0]+k,comp(0,0));
inc(p0[0],p1[0],h0,h1,w0[0],w1[0]);
fill(w0[1],w0[1]+k,comp(0,0));
fill(w1[1],w1[1]+k,comp(0,0));
inc(p0[1],p1[1],h0,h1,w0[1],w1[1]);
tie(p[0],p[1])=iDFT(w0[0],w1[0],w0[1],w1[1]);
p[0].resize(n),p[1].resize(n);
static comp q0[3][M],q1[3][M];
static comp G0[2][3][M],G1[2][3][M];
DFT(p[0],p0[0],p1[0]);
DFT(p[1],p0[1],p1[1]);
for(int c:{0,1,2})DFT(q[c],q0[c],q1[c]);
for(int i:{0,1})for(int j:{0,1,2}){
fill(G0[i][j],G0[i][j]+k,comp(0,0));
fill(G1[i][j],G1[i][j]+k,comp(0,0));
}
for(int i:{0,1})for(int j:{0,1,2}){
inc(p0[i],p1[i],q0[j],q1[j],G0[i][j],G1[i][j]);
}
for(int j:{0,1,2}){
tie(res.G[0][j],res.G[1][j])=iDFT(G0[0][j],G1[0][j],G0[1][j],G1[1][j]);
res.G[0][j].resize(n),res.G[1][j].resize(n);
}
res.G[0][0]+=L.G[0][0];
res.G[0][2]+=L.G[0][2];
res.G[1][1]+=R.G[1][1];
res.G[1][2]+=R.G[1][2];
return res;
}
int main(){
Poly::Init();
scanf("%d%d%d%d",&sid,&n,&m,&mod);
Fast=fastmod(mod);
if(mod==1)puts("0"),exit(0);
base=sqrt(mod);
for(int i=0;i<m;i++)scanf("%d",&a[i]);
for(int i=0;i<n;i++)scanf("%d",&b[i]);
for(int i=0;i<=m;i++)scanf("%d",&c[i]);
for(int i=1;i<=m;i++)scanf("%d",&d[i]);
for(int i=0;i<=n;i++)scanf("%d",&e[i]);
for(int i=0;i<=m;i++)scanf("%d",&f[i]);
poly h=solve(0,n)[1];
h.resize(n+1);
// debug(h);
node res=divide(0,m);
poly f=res.calc(c[m]),g=res.G[0][2];
reverse(all(f));
expand(g,f,inv(f,n+1),n+1);
// debug(f);
// for(int i:{0,1})for(int j:{0,1,2}){
// poly t;
// for(int x=0;x<res.G[i][j].size()&&x<10;x++)t.push_back(res.G[i][j][x]);
// debug(i,j,t);
// }
// debug(g,res.G[0][2],h,f);
int ans=0;
for(int i=0;i<=n;i++)ans=Fast.reduce(ans+1ll*h[i]*g[i]);
cout<<ans<<endl;
return 0;
}
#ifdef DEBUG
#include"debug.hpp"
#endif
詳細信息
Subtask #1:
score: 3
Accepted
Test #1:
score: 3
Accepted
time: 198ms
memory: 137540kb
input:
1 5000 5000 998244353 121811167 379924090 361631583 174189813 559424693 889647308 193102812 469875055 32237660 96186933 624360154 404866088 859165067 748410791 926700198 368632735 476560636 798138824 17883437 712872225 448819400 33122704 572152288 627010263 336722521 775918346 465722630 681224329 60...
output:
698779876
result:
ok single line: '698779876'
Test #2:
score: 3
Accepted
time: 231ms
memory: 121680kb
input:
1 4999 4919 998244353 380477138 780960797 787883474 484131625 121182688 933501638 947532778 257948759 108946829 468475856 5564419 677097370 766236309 678789875 533319074 885579006 769287005 710724535 260200529 599758240 380918586 216469888 78561030 325936496 189815268 268769489 232850763 937923688 9...
output:
475720945
result:
ok single line: '475720945'
Test #3:
score: 3
Accepted
time: 189ms
memory: 204868kb
input:
1 4995 4997 998244353 267305461 291432119 107593765 530653184 893921215 15414240 991509792 601027626 313017049 827685069 650321853 385956762 140661695 303322469 142427516 910941336 265371405 731125266 512689773 723594553 552396112 379799950 43662480 666390792 938399292 144960568 817187890 428532063 ...
output:
568578871
result:
ok single line: '568578871'
Subtask #2:
score: 0
Time Limit Exceeded
Test #4:
score: 0
Time Limit Exceeded
input:
2 200000 200000 998244353 903563506 433239074 632684755 970178226 831892753 932120646 157832416 517140217 296101978 998244343 850946564 2367119 708278025 376919151 752106478 994362560 806760771 672325565 9 958330492 343658496 153627310 330649130 983441587 829707074 135609242 706388812 325297147 4972...
output:
result:
Subtask #3:
score: 0
Time Limit Exceeded
Test #7:
score: 0
Time Limit Exceeded
input:
3 200000 200000 998244353 493605813 622283646 579332647 528537957 211102509 336893985 106292723 166710741 443808575 180234697 744331593 252016663 693453924 975202110 519712748 174749950 250990381 584528219 619047448 641168296 914918741 785005029 433175528 400547992 845115512 278159630 227330862 6407...
output:
result:
Subtask #4:
score: 0
Skipped
Dependency #2:
0%
Subtask #5:
score: 0
Skipped
Dependency #3:
0%
Subtask #6:
score: 0
Time Limit Exceeded
Test #16:
score: 0
Time Limit Exceeded
input:
6 200000 200000 998244353 401806059 107033001 530043262 862506025 263940497 48524969 232075248 849682830 420464058 64900333 394986647 954304290 957385577 86269798 579307969 896967626 230611640 527078096 39773429 402432856 495204529 272090833 100466767 562115973 196636941 736050044 580541546 81233872...
output:
result:
Subtask #7:
score: 0
Runtime Error
Dependency #1:
100%
Accepted
Test #18:
score: 16
Accepted
time: 1996ms
memory: 446532kb
input:
7 200000 20000 998244353 869285118 18064361 457499026 292378234 45941854 157946840 586178769 392380503 830348035 141601898 591275235 100919004 399285791 115436998 586990272 287976693 795031696 836945332 895793688 432697639 828280269 714678411 137052352 516420393 730089484 911809696 350536206 8175289...
output:
809172057
result:
ok single line: '809172057'
Test #19:
score: 16
Accepted
time: 1999ms
memory: 442404kb
input:
7 200000 19810 998244353 828902663 612852451 425506197 233025854 319333441 952074173 717042023 949076193 83452305 763673071 41376007 272593034 356441893 361994505 185035237 266625028 550156798 775373755 727044232 359307823 648601627 384158945 313651668 746883203 321976362 307448064 64684150 4186580 ...
output:
560874322
result:
ok single line: '560874322'
Test #20:
score: 0
Runtime Error
input:
7 1000 9996 998244353 233393388 143 900 282 622 588 259300855 18722608 81440606 388097181 802 119 117027019 445 244 220 321165142 193445923 884359675 276 671093341 934763449 844222944 251 190039071 208 521 758 621 722 370522729 731 968984566 656850987 42380471 798 292 324 609 606 400 210 785 816 863...
output:
result:
Subtask #8:
score: 0
Skipped
Dependency #6:
0%
Subtask #9:
score: 0
Skipped
Dependency #5:
0%
Subtask #10:
score: 15
Accepted
Dependency #1:
100%
Accepted
Test #32:
score: 15
Accepted
time: 8514ms
memory: 607440kb
input:
10 100000 100000 856853193 287061150 779504426 21691247 494814415 381655016 536089292 240188530 458291018 332927950 428352746 351529999 258956585 651084688 268523951 338285674 719419445 165275422 367200319 35308342 563282834 763880581 117326555 284413760 207571906 703023023 622478929 212959189 34094...
output:
304611769
result:
ok single line: '304611769'
Test #33:
score: 15
Accepted
time: 8500ms
memory: 614764kb
input:
10 99996 99997 653184000 466780448 535452791 494399809 577708013 478667201 237421741 395730779 45154159 498661837 490060453 482125361 487937293 157588691 293334157 321521203 332545607 379473949 284060041 248007589 586611611 608983811 260677141 333698719 223055627 87263221 229163593 28977457 18266932...
output:
420309862
result:
ok single line: '420309862'
Test #34:
score: 15
Accepted
time: 8430ms
memory: 620856kb
input:
10 99999 90909 993244353 662162902 368244673 342499724 545049098 136506796 132436037 290223682 406097143 860074972 162846125 724197628 121400297 113044490 571603127 804520820 716276159 223707430 992306213 67492417 849796319 195226523 811081288 878152369 146106266 297648880 82596461 645880612 8404165...
output:
988875128
result:
ok single line: '988875128'
Test #35:
score: 15
Accepted
time: 8608ms
memory: 647500kb
input:
10 99939 99191 619701811 471592989 63987447 296515528 434393809 417522560 235747800 318375577 493346545 293408357 502026258 384261946 2633459 211063149 511625485 317222583 159798065 478842502 299419646 341333878 214971597 216954473 284823472 514945706 380116339 499467361 423121831 184869643 21045491...
output:
170476426
result:
ok single line: '170476426'
Test #36:
score: 15
Accepted
time: 8568ms
memory: 646420kb
input:
10 100000 100000 761140380 535267356 745353877 500892797 72821999 206782603 274141687 238741351 705785503 33076811 685974761 141313651 487155329 758438399 740389121 653321807 242325899 271642201 382683239 328197257 364100593 754134917 394678301 686138447 541301689 274967291 220724737 688145503 38492...
output:
389683306
result:
ok single line: '389683306'