【洛谷 1357】 花园
2016-03-10 19:01
399 查看
“<<” 的运算优先级低于 ‘+’!!!
貌似对矩阵理解更深刻了!
要求有不超过K个C形花圃,对应其二进制形式中的0不超过K个。
标记出0~2^M-1中满足条件的状态x,
对于每个状态x,前M个花圃会出现1次
f(i,x)表示前i个花圃中,最后M个花圃的状态是x的方案数。
例:N=6,M=2,K=1
x取01,10,11
f(2,01)增加1个花圃,可以得到状态f(3,10)和f(3,11)
f(2,10)增加1个花圃,可以得到状态f(3,01)
f(2,11)增加1个花圃,可以得到状态f(3,10)和f(3,11)
花圃围成一圈,要使任意相邻的M个都满足要求,
对于每个状态x,由f(M,x)出发,求f(N+M,x)即可
再累加求得结果。
状态x增加1位后可能产生的状态:
x%2^(m-1)2, x%2^(m-1)2+1
复杂度:O(N)
40%的数据中,N<=20;
60%的数据中,M=2;
80%的数据中,N<=10^5。
100%的数据中,N<=10^15。 会超时。
加速优化:
考虑状态x从何而来?
x/2 和 x/2+2^(M-1)
例:M=5,K=3,状态00111 可以由 00011 和 10011 再加一个1得到。
用矩阵乘法来实现:
N=6,M=2,K=1,
(1 1 0 0)
(f(m,00) f(m,01) f(m,10) f(m,11)) * (0 0 1 1)
(1 1 0 0)
(0 0 1 1)
利用矩阵乘法快速幂优化加速。
貌似对矩阵理解更深刻了!
以下题解摘自网络
2<=M<=5,相邻的M个花圃可能有2^M种状态 ,用0~2^M-1来表示要求有不超过K个C形花圃,对应其二进制形式中的0不超过K个。
标记出0~2^M-1中满足条件的状态x,
对于每个状态x,前M个花圃会出现1次
f(i,x)表示前i个花圃中,最后M个花圃的状态是x的方案数。
例:N=6,M=2,K=1
x取01,10,11
f(2,01)增加1个花圃,可以得到状态f(3,10)和f(3,11)
f(2,10)增加1个花圃,可以得到状态f(3,01)
f(2,11)增加1个花圃,可以得到状态f(3,10)和f(3,11)
花圃围成一圈,要使任意相邻的M个都满足要求,
对于每个状态x,由f(M,x)出发,求f(N+M,x)即可
再累加求得结果。
状态x增加1位后可能产生的状态:
x%2^(m-1)2, x%2^(m-1)2+1
复杂度:O(N)
40%的数据中,N<=20;
60%的数据中,M=2;
80%的数据中,N<=10^5。
100%的数据中,N<=10^15。 会超时。
加速优化:
考虑状态x从何而来?
x/2 和 x/2+2^(M-1)
例:M=5,K=3,状态00111 可以由 00011 和 10011 再加一个1得到。
用矩阵乘法来实现:
N=6,M=2,K=1,
(1 1 0 0)
(f(m,00) f(m,01) f(m,10) f(m,11)) * (0 0 1 1)
(1 1 0 0)
(0 0 1 1)
利用矩阵乘法快速幂优化加速。
#include <cstdio> #include <cstring> #define MO 1000000007 #define LL long long LL n,m,k,N; LL a[40][40],b[40][40],tmp[40][40]; int can[40]; inline void F(LL fo[][40],LL to[][40]) { memset(tmp,0,sizeof(tmp)); for(int i=0;i<=N;i++) for(int j=0;j<=N;j++) for(int k=0;k<=N;k++) tmp[i][j]=(fo[i][k]*to[k][j]+tmp[i][j])%MO; for(int i=0;i<=N;i++) for(int j=0;j<=N;j++) to[i][j]=tmp[i][j]; } int main() { scanf("%lld %lld %lld",&n,&m,&k); N=(1<<m)-1; for(int i=0;i<=N;i++) { int cnt=0,x=i; while(x!=0) { if(x&1==1) cnt++; x>>=1; } if(cnt<=k) { can[i]=true; a[i>>1][i]=1; a[(i>>1)+(1<<(m-1))][i]=1; } b[i][i]=1; } while(n!=1) { if(n%2==1) F(a,b); F(a,a); n>>=1; } F(a,b); LL ans=0; for(int i=0;i<=N;i++) if(can[i]) ans+=b[i][i],ans%=MO; printf("%d\n",ans); return 0; }
相关文章推荐
- 【BZOJ 1012】 [JSOI2008]最大数maxnumber
- 【洛谷 2161】 [Shoi2009]Booking 会场预约
- 【BZOJ 1798】[Ahoi2009]Seq 维护序列seq
- 【CodeVS 1540】银河英雄传说 2002年NOI全国竞赛
- 【洛谷 1991】 无线通讯网
- 【洛谷 1345】 奶牛的电信
- 【BZOJ 3990】 [SDOI2015]排序
- 【BZOJ 2705】 [SDOI2012]Longge的问题
- 【BZOJ 1934】 [Shoi2007]Vote 善意的投票
- 【BZOJ 1433】 [ZJOI2009]假期的宿舍
- 【COGS 1873】 [国家集训队2011]happiness(吴确)
- 【Poj 3469】 Dual Core CPU
- 【BZOJ 3504 】[Cqoi2014]危桥
- 【CodeVS 1227】 方格取数2
- 【CodeVS 1028】 花店橱窗布置
- 【Poj 1149】PIGS
- Ubuntu12.04LST 下 Django+uwsgi+nginx部署
- 【Poj 2112】 Optimal Milking
- 【Poj 3436】 ACM Computer Factory
- 【Poj 1273】 Drainage Ditches