洛谷 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浮点算术:争议和限制
浮点数在计算机硬件中表示为以 2 为基数(二进制)的小数.举例而言,十进制的小数 0.125 等于 1/10 + 2/100 + 5/1000 ,同理,二进制的小数 0.001 等于0/2 + 0/4 ...
- 2.4 Oracle之DCL的SQL语句之用户权限以及三大范式
DCL (Data Control Language,数据库控制语言)用于定义数据库权限 一.用户权限 1.1 建立用户以及授权: Eg :CREATE USER 用户名 IDENTIFIED ...
- P4562 [JXOI2018]游戏
题面 题目描述 她长大以后创业了,开了一个公司. 但是管理公司是一个很累人的活,员工们经常背着可怜偷懒,可怜需要时不时对办公室进行检查. 可怜公司有 \(n\) 个办公室,办公室编号是 \(l\) 到 ...
- sqli-labs学习笔记 DAY8
DAY 8 sqli-lab Page-3 sqli-labs lesson 38 What is Stacked injection? https://blog.csdn.net/Fly_hps/a ...
- 15 Puzzle (4乘4谜题) IDA*(DFS策略与曼哈顿距离启发) 的C语言实现
大家好!这是我的第一篇博客,由于之前没有撰写博客的经验,并且也是初入计算机和人工智能领域,可能有些表述或者理解不当,还请大家多多指教. 一.撰写目的 由于这个学期在上算法与数据结构课程的时候,其中一个 ...
- 利用Elasticsearch搭建全球域名解析记录
前言 数据来源,由Rapid7收集并提供下载https://scans.io/study/sonar.fdns 下载Elasticsearch 2.3 ElasticSearch是一个基于Lucene ...
- Class-dump 安装和使用记录(导出应用的头文件)
class-dump算是逆向工程中一个入门级的工具,可以很方便的导出程序头文件,可以轻松的了解程序结构方便逆向.安装包下载地址:http://stevenygard.com/projects/clas ...
- 20162314 《Program Design & Data Structures》Learning Summary Of The Second Week
20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Second Week ...
- 《JavaScript》forEach()和map()
js中的forEach()方法只能遍历数组,不能遍历字符串和对象,和$.each()有很多使用上的区别array.forEach(funcion(value,index,arr){},thisValu ...
- 第三周作业(一)VS安装及单元测试练习
第三周作业(一) 需求:练习教科书第22~25页单元测试练习,要求自行安装Visual Studio开发平台,版本至少在2010以上,要求把程序安装过程和练习过程写到博客上,越详细越好,要图文并茂,没 ...