bzoj 5003: 与链
来源:互联网 发布:海岛奇兵能量神像数据 编辑:程序博客网 时间:2024/06/06 15:56
前言
这题是羊教我的
题解
由于有自环,所以每个数其实就是可以选任意次
考虑你选出来的k个数,从上往下看,对于每一位,肯定都是一段1,然后一段0的形式
于是我们就可以吧每一位都分开考虑
其实就是每一位可以选择不超过k个1,然后要你选出来和为n,问你方案数。。
然后我们可以DP
然后对于每一个,我们可以枚举这一位放多少个1来转移
但是这样是
我们发现,对于一个数i,他减多少个
于是我们就可以统计一个前缀和,搞一搞就可以了
CODE:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;typedef long long LL;const LL MOD=1e9+9;const LL N=100005;LL k,n;LL f[2][N];//前i位,和为j有多少种方案LL h[N];//当前膜2^i 的前缀和是多少int main(){ memset(f,0,sizeof(f)); scanf("%lld%lld",&k,&n); f[0][0]=1; int st=0; for (LL u=0;u<=19;u++)//多少位 { memset(h,0,sizeof(h)); LL x=1<<u; if (x>n) break; st^=1; for (int i=0;i<=n;i++) { h[i%x]=(h[i%x]+f[st^1][i])%MOD; if (i-x*(k+1)>=0) h[i%x]=(h[i%x]-f[st^1][i-x*(k+1)]+MOD)%MOD; f[st][i]=h[i%x]; } } printf("%lld\n",f[st][n]); return 0;}
阅读全文