洛谷 P1357 花园 解题报告
P1357 花园
题目描述
小\(L\)有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为\(1~N(2<=N<=10^{15})\)。他的环形花园每天都会换一个新花样,但他的花园都不外乎一个规则,任意相邻\(M(2<=M<=5,M<=N)\)个花圃中有不超过\(K(1<=K<M)\)个\(C\)形的花圃,其余花圃均为\(P\)形的花圃。
例如,\(N=10,M=5,K=3\)。则
\(CCPCPPPPCC\)是一种不符合规则的花圃;
\(CCPPPPCPCP\)是一种符合规则的花圃。
请帮小\(L\)求出符合规则的花园种数\(Mod\) 1000000007
由于请您编写一个程序解决此题。
输入输出格式
输入格式:
一行,三个数\(N,M,K\)。
输出格式:
花园种数\(Mod\) 1000000007
说明
40%的数据中,\(N<=20\);
60%的数据中,\(M=2\);
80%的数据中,\(N<=10^5\)。
100%的数据中,\(N<=10^{15}\)。
这道题的思维难度是真的大(也可能是我菜)
请顺着看(我就是因为直接看别人题解没彻底理解前面的就去往后翻导致理解了很久)
80分给了状压DP
不考虑环时
令\(dp[i][j]\)代表当进行到第\(i\)个位置时,前\(M\)位的状态为\(j\)
\(dp[i][j]=dp[i-1][k]\),\(k\)为合法的前一位状态。
关于状压的思路,有两个导向性。
(1) \(2<=M<=5\)
(2) 当进行转移时,要想知道合不合法得知道前\(M\)位上的所有数。
当然,如果想不到如何处理环,状压的80分也白瞎。
想想在状压中,我们的状态实质上是一个区间,我们进行递推的时候,实际上相当于把这个区间向右滑动。
如果我们这时候只对一个初始合法区间\(j_0\)进行移动,当移动了\(n\)次以后,它可能到达很多个状态。但是如果它和自己重合了,不就连成了一个环了吗?
这时候\(dp[n][j_0]\)就代表只移动合法区间\(j_0\)所构成的环的方案数。
我们把每个初始合法区间都做一次这样的状压\(DP\),统计答案。
复杂度:\(O(M!^3*N)\)
当然实际上我们通过预处理,可以得到类似\(dx[i][j]\)这样的数组,表示状态\(i\)是否可以到达状态\(j\)。使复杂度远远达不到上界。
我们发现,\(N\)的长度和\(dx[i][j]\)没有什么关系,而\(dx[i][j]\)又是一个矩阵。
那么当忽略\(i\)这一维度时,\(dp[j]\)通过\(dx[i][j]\)向后一位进行递推,不就是矩阵乘法吗?

左边是推到某一位了,和右边矩阵相乘得到下一位。
可以直接用矩阵快速幂求解可达性矩阵的\(N\)次方,然后与每一个初始合法状态相乘。
我们发现,可达性矩阵和第\(j\)个状态的初始矩阵进行相乘后,只能取\((j,j)\)位置的值,所以最终的答案即是可达性矩阵乘方后对角线值之和。
Code:
#include <cstdio>
#include <cstring>
#define ll long long
const int N=123;
const ll mod=1e9+7;
ll n;
int m,k,len;
struct matrix
{
ll dx[N][N];
matrix()
{
memset(dx,0,sizeof(dx));
}
matrix friend operator *(matrix n1,matrix n2)
{
matrix n3;
for(int i=0;i<=len;i++)
for(int j=0;j<=len;j++)
for(int k=0;k<=len;k++)
n3.dx[i][j]=(n3.dx[i][j]+n1.dx[i][k]*n2.dx[k][j])%mod;
return n3;
}
}d,f;
bool check(int x)
{
int cnt=k;
while(x)
{
cnt--;
x-=x&-x;
}
return cnt>=0;
}
void init()
{
scanf("%lld%d%d",&n,&m,&k);//m中不超过k个1
len=(1<<m)-1;
for(int i=0;i<=len;i++)
{
if(!check(i))
continue;
int to=(i<<1)&len;
if(!check(to))
continue;
d.dx[to][i]=1;
to=to|1;
if(!check(to))
continue;
d.dx[to][i]=1;
}
for(int i=0;i<=len;i++)
f.dx[i][i]=1;
}
void quick_pow()
{
while(n)
{
if(n&1)
f=f*d;
d=d*d;
n>>=1;
}
}
void work()
{
quick_pow();
ll ans=0;
for(int i=0;i<=len;i++)
ans=(ans+f.dx[i][i])%mod;
printf("%lld\n",ans);
}
int main()
{
init();
work();
return 0;
}
2018.7.2
洛谷 P1357 花园 解题报告的更多相关文章
- 题解:洛谷P1357 花园
题解:洛谷P1357 花园 Description 小 L 有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为 \(1∼n\).花园 \(1\) 和 \(n\) 是相邻的. 他的环形花园每天都会换 ...
- 洛谷 P2058 海港 解题报告
P2058 海港 题目描述 小K是一个海港的海关工作人员,每天都有许多船只到达海港,船上通常有很多来自不同国家的乘客. 小K对这些到达海港的船只非常感兴趣,他按照时间记录下了到达海港的每一艘船只情况: ...
- 洛谷 P3956 棋盘 解题报告
P3956 棋盘 题目描述 有一个\(m×m\)的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能 ...
- 洛谷 P1979 华容道 解题报告
P1979 华容道 题目描述 小\(B\)最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时 ...
- BZOJ 3545 / 洛谷 P4197 Peaks 解题报告
P4197 Peaks 题目描述 在\(\text{Bytemountains}\)有\(N\)座山峰,每座山峰有他的高度\(h_i\).有些山峰之间有双向道路相连,共\(M\)条路径,每条路径有一个 ...
- 虔诚的墓主人(BZOJ1227)(洛谷P2154)解题报告
题目描述 小W是一片新造公墓的管理人.公墓可以看成一块N×M的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地. 当地的居民都是非常虔诚的基督徒,他们愿意提前为自己找一块合适墓地. ...
- [洛谷P1357] 花园
题目类型:状压\(DP\) -> 矩阵乘法 绝妙然而思维难度极其大的一道好题! 传送门:>Here< 题意:有一个环形花圃,可以种两种花:0或1. 要求任意相邻的\(M\)个花中1的 ...
- 洛谷P1357 花园(状态压缩 + 矩阵快速幂加速递推)
题目链接:传送门 题目: 题目描述 小L有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为1~N(<=N<=^).他的环形花园每天都会换一个新花样,但他的花园都不外乎一个规则,任意相邻 ...
- 洛谷 P2672 推销员 解题报告
P2672 推销员 题目描述 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有N家住户,第i家住户到入口的距离为 ...
随机推荐
- .Net 如何访问主流的各大数据库
做过开发的都知道,.NET基本可以理解是和MSSQL,windows服务器属于一个好的搭档,正如PHP和MYSQL,LIUNX等也可以理解是一个完美搭配:但是在实际的开发中并不完全是这样的,如果你是学 ...
- 005 -- Mysql数据库引擎特点分析
常用的数据库引擎的特点: ISAM: ISAM是一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到数据库查询次数要远大于更新次数.因此,ISAM执行读取操作的速度很快,而且不占用大量的 ...
- 【Go】Mac上安装Go
一:首先安装brew,方便管理,安装方法,终端中输入 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/ins ...
- Docker容器的启动与停止
启动docker:systemctl start docker 停止docker:systemctl stop docker 重启docker:systemctl restart docker 查看d ...
- Tree - AdaBoost with sklearn source code
In the previous post we addressed some issue of decision tree, including instability, lack of smooth ...
- bitcoin PoW原理及区块创建过程
bitcoin PoW原理及区块创建过程 PoW 为了在点对点的基础上实现一个分布式时间戳服务器,我们需要使用PoW(Proof of Work)系统来达成共识.PoW过程就是寻找一个目标值的过程,当 ...
- openssl在多平台和多语言之间进行RSA加解密注意事项
首先说一下平台和语言: 系统平台为CentOS6.3,RSA加解密时使用NOPADDING进行填充 1)使用C/C++调用系统自带的openssl 2)Android4.2模拟器,第三方openssl ...
- Django_QueryDict
介绍 class QueryDict(MultiValueDict): """ A specialized MultiValueDict which represents ...
- Bing词典vs有道词典比对测试报告——体验篇之成长性及用户控制权
成长性: 会记住曾经查询过的单词或例句与有道词典实现基本一样,并无特别亮点. 用户有控制权: 必应词典和有道词典都能实现基本的查询前进和后退.以及无法查找结果,能顺利进行反馈. 我们在输入完单词按下回 ...
- No.111_第四次团队会议
后端的偏执 啊,这次又轮到我写团队博客了. 此时又是深夜,窗外漫天繁星.舍友的呼噜声惊吓了月亮,它害羞地跑回了云里去. 我关上灯拔掉机械,悄悄拿着电脑上了床,写这次的团队博客.曾经觉得自己绝对不会晚睡 ...