CF1696E Placing Jinas 题解

可能更好的阅读体验

题目传送门

upd on 2022.9.13:好像有点小问题在洛谷评论里面被指出,已经修改。

题目大意

给定一个 单调不增 的序列 a,第 0n 项为 a1,a2,,an,之后的为全 0
对平面直角坐标系上的每个整点进行染色,对于一个点 (x,y) 如果 y<ax 那么这个点位白色,否则为黑色。
每次操作你可以使点 (x,y) 上的娃娃数量减一,同时 (x,y+1)(x+1,y) 上的娃娃数量都会加一。
现在在 (0,0) 上有一个娃娃,求让所有的白色点上都没有娃娃的操作数量,对 109+7 取模。
n2×105,0ai2×105

题目解析

f(x,y) 为对点 (x,y) 实行的操作次数。
我们发现,当 x=0 或者是 y=0 的时候,f(x,y)=1,否则 f(x,y)=f(x1,y)+f(x,y1)
我们发现这个递推式像杨辉三角的递推式,不难得到 f(x,y)=Cx+yx

那么答案就是

i=0nj=0ai1f(i,j)

但是这样求是 O(n2) 的,所以需要考虑化简这个式子。
注意到

i=0nf(x,i)=f(x,0)+f(x,1)+f(x,2)+f(x,3)++f(x,n)=f(x+1,0)+f(x,1)+f(x,2)+f(x,3)++f(x,n)=f(x+1,1)+f(x,2)+f(x,3)+f(x,n)=f(x+1,n)

所以答案就是

i=0nj=0ai1f(i,j)=i=0nf(i+1,ai1)=i=0nCai+ii+1

代码:

int n,a[maxn]; ll fact[maxn],inv[maxn],ans;
ll mpow(ll x,ll y){
ll res=1,tmp=x%MOD;
while(y){
if(y&1) res=res*tmp%MOD;
y>>=1; tmp=tmp*tmp%MOD;
} return res;
}
void init(){
int i; inv[0]=fact[0]=1; for(i=1;i<=N;i++) fact[i]=fact[i-1]*i%MOD;
inv[N]=mpow(fact[N],MOD-2); for(i=N-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%MOD; return;
}
ll C(int x,int y){ return fact[x]*inv[y]%MOD*inv[x-y]%MOD; }
int main(){
n=read(); int i; for(i=0;i<=n;i++) a[i]=read(); init();
for(i=0;i<=n;i++) if(a[i]>=1) ans+=C(a[i]+i,i+1),ans%=MOD;
print(ans%MOD); return 0;
}
posted @   jiangtaizhe001  阅读(142)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示