洛谷 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家住户到入口的距离为 ...
随机推荐
- 使用python实现解析二元一次方程
二元一次函数的实现 import cmathimport mathimport sys 这里导入cmath包是在后面用来处理复数的情况导入math使用来处理 平方 根号等的运算而导入sys的意义是为了 ...
- Linux常规命令总结
Linux常规命令总结,仅供参考: 系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显 ...
- 中国的互联网企业逐步走向“单一企业多样化,商业生态同质化”,美国的互联网企业则会走向“单一企业专业化,商业生态多样化”:3.5星|《VUCA时代,想要成功,这些原则你一定得明白》
VUCA时代,想要成功,这些原则你一定得明白(<哈佛商业评论>增刊) <哈佛商业评论>的10篇文章的合集.主题是VUCA时代,也就是当前复杂多变难预测的时代.大部分文章都是点到 ...
- 关于MySql数据库主键及索引的区别
一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...
- Ruby知识点三:运算符
1.逻辑运算符 (1)条件1 || 条件2 条件1为假时,才需判断条件2 (2)条件1 && 条件2 条件1为真时,才需判断条件2 2.范围运算符 (1)x..y 从x到y,包括y ...
- vim 多个文件切换 :b 命令
MiniBufExplorer插件的使用 博客分类: vim vimMiniBufExplorer 快速浏览和操作Buffer -- 插件: MiniBufExplorer 下载地址 [http:// ...
- Hibernate笔记②--hibernate类生成表、id生成策略、级联设置、继承映射
一.多表的一个关联关系 老师和学生是一对多的关系 student:tid属性 外键约束 对应teacher表中的id属性 teacher:id 在myeclipse的db窗口中选中两个表来生成类. ...
- System 类的使用
/*System 系统类 主要用于获取系统的属性数据.System类常用的方法: arraycopy(Object src, int srcPos, Object dest, int destPos, ...
- stateful openflow------整理openstate原理以及具体应用
openstate基本思想就是控制器下放一部分功能,交换机不再是简单的dumb,而是保留一些简单的wise. 论文中以端口锁定为例,提出了米粒型状态机在交换机内部的应用从而可以大大减少交换机和控制器之 ...
- NServiceBus官方文档翻译(一)NServiceBus 概况
NServiceBus 概况 NServiceBus 被设计用来组合面向业务的服务,它并不是用来替代诸如 WCF 一类的RPC技术. NServiceBus 不只包含通信模块,像其他成熟的SOA和DD ...