1 条题解
-
0
自动搬运
来自洛谷,原作者为

Acoipp
We shall never surrender!搬运于
2025-08-24 22:23:18,当前版本为作者最后更新于2024-08-23 20:59:11,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
首先考虑给的集合 到达 ,有一些点的位置会发生变化,设有 个,那么剩下 个没有发生变化,那么有结论 的方案数只跟 有关。
这个方案可以直接矩阵乘法求出来,设矩阵为 ,那么 的构造是容易的,只需要设置一个阈值 ,预处理出 以及 就可以实现 查询出来在 (题面中的意思)固定的情况下每个 的方案数。
这一部分预处理时间复杂度是 的。
然后考虑处理出 表示与集合 中不同的元素(某个物品在 中的位置与在 中的位置不一样)有 个的 的所有得分之和。
这个 我们可以用类似于高维前缀和的方法处理,大概就是枚举 ,然后 存的是所有 与 在前 位有 个不同,并且后 位与 完全相同的 的得分之和。
最后只需要枚举第 位填的是什么即可。
于是就可以用高维前缀和的套路优化了,这部分的时间复杂度是 。
整体来说呢,需要卡卡常才能过。
#include<bits/stdc++.h> #define ll long long #define N 1000005 #define mod 998244353 using namespace std; ll n,k,q,i,j,l,l2,up,val[N],qm[N],ans=1,a,b,anss[21][21],temp[21][21],g[N][21],h[N][21],p[21],inv[21],C[25][25],B,ps; int f[32005][21][21],f2[32005][21][21]; inline ll qmi(ll a,ll b,ll p){ ll res = 1%p,t = a; while(b){ if(b&1) res=res*t%p; t=t*t%p; b>>=1; } return res; } inline void times(ll a[21][21],int b[21][21],ll n1,ll n2,ll n3){ for(ll i=0;i<=n1;i++) for(ll j=0;j<=n2;j++) for(ll k=0;k<=n3;k++) temp[i][k]=(temp[i][k]+a[i][j]*b[j][k])%mod; for(ll i=0;i<=n1;i++) for(ll k=0;k<=n3;k++) a[i][k]=temp[i][k],temp[i][k]=0; } inline char nc(){ static char buf[1000000],*p=buf,*q=buf; return p==q&&(q=(p=buf)+fread(buf,1,1000000,stdin),p==q)?EOF:*p++; } inline ll read(){ ll res = 0,w = 1; char c = nc(); while(c<'0'||c>'9')w=(c=='-'?-1:w),c=nc(); while(c<='9'&&c>='0')res=res*10+c-'0',c=nc(); return res*w; } char obuf[1<<21],*p3=obuf; inline void pc(char c){ p3-obuf<=(1<<20)?(*p3++=c):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=c); } inline void write(ll x){ if(x<0) pc('-'),x=-x; if(x>9) write(x/10); pc(x%10+'0'); } int main(){ n=read(),k=read(),q=read(),up=qmi(n,k,mod),B=sqrt(mod); qm[0]=1; for(i=1;i<=k;i++) qm[i]=qm[i-1]*n; for(i=0;i<up;i++) val[i]=read(),g[i][0]=val[i]; for(i=0;i<k;i++){ for(j=0;j<up;j++){ for(l=0;l<=i;l++){ (h[j][l] = (h[j][l]+g[j][l]))>=mod&&(h[j][l]-=mod); (h[j][l+1] = (h[j][l+1]-g[j][l]))<0&&(h[j][l+1]+=mod); } if((j/qm[i])%n==0){ memset(p,0,sizeof(p)); for(l=0;l<n;l++) for(l2=0;l2<=i;l2++) (p[l2+1]=(p[l2+1]+g[j+l*qm[i]][l2]))>=mod&&(p[l2+1]-=mod); for(l=0;l<n;l++) for(l2=0;l2<=i+1;l2++) (h[j+l*qm[i]][l2]=(p[l2]+h[j+l*qm[i]][l2]))>=mod&&(h[j+l*qm[i]][l2]-=mod); } } for(j=0;j<up;j++) for(l=0;l<=i+1;l++) g[j][l]=h[j][l],h[j][l]=0; } C[0][0]=1; for(i=0;i<=k;i++){ for(j=0;j<=k;j++){ if(i) C[i][j]+=C[i-1][j]; if(i&&j) C[i][j]+=C[i-1][j-1]; if(C[i][j]>=mod) C[i][j]-=mod; } } for(i=0;i<=k;i++){ if(i) f[1][i][i-1]=(f[1][i][i-1]+i)%mod,f[1][i][i]=(f[1][i][i]+1ll*i*(n-2))%mod; if(k-i) f[1][i][i+1]=(f[1][i][i+1]+1ll*(k-i)*(n-1))%mod; } for(i=2;i<=B;i++){ for(j=0;j<=k;j++) for(l=0;l<=k;l++) for(ps=0;ps<=k;ps++) f[i][j][ps]=(f[i][j][ps]+1ll*f[i-1][j][l]*f[1][l][ps])%mod; } for(i=0;i<=k;i++) for(j=0;j<=k;j++) f2[1][i][j]=f[B][i][j]; for(i=2;i<=(mod/B);i++){ for(j=0;j<=k;j++) for(l=0;l<=k;l++) for(ps=0;ps<=k;ps++) f2[i][j][ps]=(f2[i][j][ps]+1ll*f2[i-1][j][l]*f2[1][l][ps])%mod; } for(i=0;i<=k;i++) inv[i]=qmi(C[k][i],mod-2,mod)*qmi(qmi(n-1,i,mod),mod-2,mod)%mod; while(q--){ a=read(),b=read(); b=b*ans%mod; for(i=0;i<=k;i++) anss[0][i]=0; anss[0][0]=1; if(b/B) times(anss,f2[b/B],0,k,k); if(b%B) times(anss,f[b%B],0,k,k); for(i=0,ans=0;i<=k;i++) ans=(ans+anss[0][i]*g[a][i]%mod*inv[i])%mod; write(ans),pc('\n'); } return fwrite(obuf,p3-obuf,1,stdout),0; }
- 1
信息
- ID
- 5738
- 时间
- 5000ms
- 内存
- 500MiB
- 难度
- 7
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者