2021.3.16爆零赛
2021.3.16爆零赛
题面:链接: https://pan.baidu.com/s/1Kqo-eupvcdk25pm_Dmy0YQ 提取码: eykg
吐了,期望:80+20+5,实际:50+20+5
大常数竟是我自己
考试时打第二题时证了个假的时间复杂度,然后兴致勃勃地打起了第一题。现在非常后悔,非常后悔😃
第一题不是很难,先推了下\(dp\)式,弄下生成函数,然后就调了3个小时😄,弄了个\(80pt\)的部分分,最后被卡常掉了\(30pt\)
结果第三题没怎么看,现在想来\(30pt\)也不是很难拿
以后还是要多康下部分分,小蒟蒻还是不要一来就去盯着正解\((个\_个)\)
T1.染色问题
比较简单,定义状态\(f_{i,j}\)为从后往前涂,涂完第\(j\)种颜色,剩余\(i\)个位置无色的方案数。
易得如下转移方程
\[f_{x,1}=x+1(x<n)\\f_{x,y}=f_{x,y-1}+(x+1)\sum_{i=1}^\infty f_{x+i,y-1}\\\\
\]
我们设\(g_{x,y}=\sum_{i=y}^\infty f_{i,x}\),可得如下递推式
\[g_{i,j}=g_{i,j+1}+g_{i-1,j}-g_{i-1,j+1}+(j+1)g_{i-1,j+1}\\
=g_{i,j+1}+g_{i-1,j}+jg_{i-1,j+1}\\
\]
令\(g_y\)表示\(g_{x,y}\)关于\(x\)的生成函数
不难得到下式
\[g_j+1={(1+jx)(g_{j+1}+1)\over 1-x}\\
g_0+1=(g_{n-1}+1)\prod_{i=0}^{n-2}{1+ix\over 1-x}\\
g_1+1=(g_{n-1}+1)\prod_{i=1}^{n-2}{1+ix\over 1-x}
\]
我们可以分治\(NTT\)求出\(\prod (1+ix)\),再多项式快速幂求出\(({1\over 1-x})^k\)
时间复杂度为:
\[T(n)=2T(\frac{n}{2})+n\log_2n
\]
能得\(80pt\)可这关一个被卡常的人什么事?
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define Type template<typename T>
# define read read1<ll>()
Type T read1(){
T t=0;
char k;
bool vis=0;
do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define mod 998244353
int n,m;
namespace A{
int f[5005][5005],g[5005][5005];
int MAIN(){
for(int i=n;i--;)g[1][i]=g[1][i+1]+(f[1][i]=i+1);
for(int i=2;i<=m;++i)
for(int j=n;j--;)
g[i][j]=(g[i][j+1]+(f[i][j]=(f[i-1][j]+1ll*(j+1)*g[i-1][j+1])%mod))%mod;
cout<<f[m][0];
return 0;
}
}
namespace B{
const int g=3,invg=332748118,inv2=499122177;
int r[2097153],gv[33005][2],nv[33005][2],invt[2097153];
void init(const int N=32768){
gv[0][0]=nv[0][0]=gv[0][1]=nv[0][1]=1;
for(int i=1;i<=N;++i)nv[i][0]=1ll*nv[i-1][0]*g%mod;
for(int i=1;i<=N;++i)nv[i][1]=1ll*nv[i-1][1]*nv[N][0]%mod;
for(int i=1;i<=N;++i)gv[i][0]=1ll*gv[i-1][0]*invg%mod;
for(int i=1;i<=N;++i)gv[i][1]=1ll*gv[i-1][1]*gv[N][0]%mod;
invt[1]=1;
for(int i=2;i<=2097152;++i)
invt[i]=1ll*(mod-mod/i)*invt[mod%i]%mod;
}
int qkpow(int n,int m){
if(!m)return 1;
ll t=qkpow(n,m>>1);t=t*t%mod;
if(m&1)t=t*n%mod;
return t;
}int Qkpow(int n,int m){
if(n==g)return 1ll*nv[m&32767][0]*nv[m>>15][1]%mod;
return 1ll*gv[m&32767][0]*gv[m>>15][1]%mod;
}int Log2(double x){
if(x==1)return 0;
return ((*(unsigned ll*)&x>>52)&1023)+1;
}
void NTT(int *a,int s,bool ty){
int L=Log2(s);r[0]=0;
for(int i=0;i<s;++i){
r[i]=(r[i>>1]>>1)|((i&1)<<L-1);
if(r[i]>i)swap(a[r[i]],a[i]);
}
for(int i=1;i<s;i<<=1){
int T=Qkpow(ty?invg:g,(mod-1)/(i<<1));
ll v=1;
for(int w=i<<1,j=0;j<s;j+=w,v=1)
for(int k=0;k<i;++k,v=1ll*v*T%mod){
int x=a[j+k],y=1ll*a[i+j+k]*v%mod;
a[j+k]=(x+y)%mod;a[i+j+k]=(x-y+mod)%mod;
}
}
if(ty){ll invs=invt[s];
for(int i=0;i<s;++i)
a[i]=invs*a[i]%mod;
}
}
int *w,*u,s=1,*v,*G,*x,*y;
void solve(int l,int r,int w,int L){
memset(x+w,0,L<<2);
if(l>r){
x[w]=1;
return;
}
if(l==r){
x[w]=1;
x[w+1]=l;
return;
}int mid=l+r>>1;
solve(l,mid,w,L>>1);
solve(mid+1,r,w+(L>>1),L>>1);
memset(y+w+(L>>1),0,L<<1);
memcpy(y+w,x+w+(L>>1),L<<1);
memset(x+w+(L>>1),0,L<<1);
NTT(x+w,L,0);NTT(y+w,L,0);
for(int i=0;i<L;++i)x[i+w]=1ll*x[i+w]*y[i+w]%mod;
NTT(x+w,L,1);
}
int* pow(int *x,int n){
int *y=new int[s]();y[0]=1;
for(;n;n>>=1){
NTT(x,s,0);
if(n&1){
NTT(y,s,0);
for(int i=0;i<s;++i)y[i]=1ll*y[i]*x[i]%mod;
NTT(y,s,1);
for(int i=m+1;i<s;++i)y[i]=0;
}
for(int i=0;i<s;++i)x[i]=1ll*x[i]*x[i]%mod;
NTT(x,s,1);
for(int i=m+1;i<s;++i)x[i]=0;
}
return y;
}
int MAIN(){init();
int M=max(n,m);
if(n==1)return puts("1"),0;
while(s<=M+M)s<<=1;u=new int[s]();
x=new int[s]();y=new int[s]();
solve(1,n-2,0,s);w=x;
for(int i=0;i<=m;++i)u[i]=1;
v=pow(u,n-1);G=new int[s]();
for(int i=1;i<=m;++i)G[i]=n;G[0]=1;
NTT(G,s,0);NTT(v,s,0);
for(int i=0;i<s;++i)G[i]=1ll*G[i]*v[i]%mod;
NTT(G,s,1);
NTT(G,s,0);NTT(w,s,0);
for(int i=0;i<s;++i)G[i]=1ll*G[i]*w[i]%mod;
NTT(G,s,1);
int vx=G[m],vv=0;
solve(1,n-2,0,s);w=x;
memset(u,0,sizeof(u));
for(int i=0;i<=m;++i)u[i]=1;
v=pow(u,n-2);G=new int[s]();
for(int i=1;i<=m;++i)G[i]=n;G[0]=1;
NTT(G,s,0);NTT(v,s,0);
for(int i=0;i<s;++i)G[i]=1ll*G[i]*v[i]%mod;
NTT(G,s,1);
NTT(G,s,0);NTT(w,s,0);
for(int i=0;i<s;++i)G[i]=1ll*G[i]*w[i]%mod;
NTT(G,s,1);vv=G[m];
cout<<(vx-vv+mod)%mod;
return 0;
}
}
int main(){
fre("color");
n=read,m=read;
if(n<=5000&&m<=5000)A::MAIN();
else B::MAIN();
return 0;
}
我们可以发现,\(\prod_{i=l}^{l+n-1}(1+ix)\)与\(\prod_{i=l+n}^{l+2n-1}(1+ix)\)有着些内在关联
令\(F(x)=x^n\prod_{i=l}^{r}(\frac{1}{x}+i)=x^n\sum_{i=0}^na_ix^{-i}\)
则右式为\(F_0(x)=x^n\sum_{i=0}^na_i(x^{-1}+n)^i\)
二项式展开:
\[\begin{align}
F_0(x)&=x^n\sum_{i=0}^na_i\sum_{j=0}^i{i\choose j}x^{-j}n^{i-j}\\
&=x^n\sum_{i=0}^ni!a_i\sum_{j=0}^i\frac{x^{-j}}{j!}.{n^{i-j}\over(i-j)!}
\end{align}
\]
差不多就是这样,咕咕咕
因果乃旋转纺车,光彩之多面明镜
浮世苍茫,不过瞬逝幻梦
善恶爱诳,皆有定数
于命运之轮中
吞噬于黄泉之冥暗
呜呼,吾乃梦之戍人
幻恋之观者
唯于万华镜中,永世长存
浮世苍茫,不过瞬逝幻梦
善恶爱诳,皆有定数
于命运之轮中
吞噬于黄泉之冥暗
呜呼,吾乃梦之戍人
幻恋之观者
唯于万华镜中,永世长存