P1357 花园
状压dp+矩乘
首先看到题目说M<=5,这么小的数据明显可以用状压保存相邻状态,于是可以得到一个80分的dp:
先筛出所有可用的状态,然后建立一个矩阵保存可转移的状态,再然后把每个状态都当成最初状态各跑一次dp,累计答案
然而我们发现,n太大了。又发现,其实每次转移可以直接用矩乘来搞(用到了状态矩阵)
于是就用矩乘了。嗯,就这样,具体看题解吧。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod=;
ll n,ans;
int m,k,cnt;
int state[];
struct matrix{
int a[][];
matrix(){memset(a,,sizeof(a));}
matrix operator * (matrix &tmp){
matrix c;
for(int i=;i<=cnt;++i)
for(int j=;j<=cnt;++j)
for(int k=;k<=cnt;++k)
c.a[i][j]=(ll)(c.a[i][j]+(ll)a[i][k]*tmp.a[k][j]%mod)%mod;
return c;
}
matrix ksm(matrix x,ll y){
matrix ans;
for(int i=;i<=cnt;++i) ans.a[i][i]=;
for(;y;y>>=){
if(y&) ans=ans*x;
x=x*x;
}
return ans;
}
}st,mul; int main(){
scanf("%lld%d%d",&n,&m,&k);
for(int i=(<<m)-;i>=;--i){
int t=;
for(int j=i;j;j>>=) t+=(j&);
if(t<=k) state[++cnt]=i;
} //筛出可用状态
for(int i=;i<=cnt;++i)
for(int j=;j<=cnt;++j)
{
int x=state[i],y=state[j]>>,ok=;
for(int k=m-;k;--k){
if((x&)!=(y&)) {ok=; break;}
x>>=; y>>=;
}
mul.a[i][j]=ok;
} //可转移状态矩阵
for(int i=;i<=cnt;++i) st.a[i][i]=;
mul=mul.ksm(mul,n);
st=st*mul;
for(int i=;i<=cnt;++i) ans=(ans+st.a[i][i])%mod; //累计矩阵对角线上的答案
printf("%lld",ans);
return ;
}
P1357 花园的更多相关文章
- 洛谷 P1357 花园 解题报告
P1357 花园 题目描述 小\(L\)有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为\(1~N(2<=N<=10^{15})\).他的环形花园每天都会换一个新花样,但他的花园都不 ...
- 题解:洛谷P1357 花园
题解:洛谷P1357 花园 Description 小 L 有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为 \(1∼n\).花园 \(1\) 和 \(n\) 是相邻的. 他的环形花园每天都会换 ...
- 洛谷P1357 花园(状态压缩 + 矩阵快速幂加速递推)
题目链接:传送门 题目: 题目描述 小L有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为1~N(<=N<=^).他的环形花园每天都会换一个新花样,但他的花园都不外乎一个规则,任意相邻 ...
- P1357 花园 状压 矩阵快速幂
题意 小L有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为1~N(2<=N<=10^15).他的环形花园每天都会换一个新花样,但他的花园都不外乎一个规则,任意相邻M(2<=M& ...
- [洛谷P1357] 花园
题目类型:状压\(DP\) -> 矩阵乘法 绝妙然而思维难度极其大的一道好题! 传送门:>Here< 题意:有一个环形花圃,可以种两种花:0或1. 要求任意相邻的\(M\)个花中1的 ...
- luogu P1357 花园
传送门 先考虑朴素dp,设\(f_{i,j}\)表示推了\(i\)次,前\(m\)个点的状态为二进制数\(j\)(这里记放C为1),转移的时候枚举下一位放什么,还要考虑是否满足C的个数\(\leq k ...
- 【洛谷】P1357 花园(状压+矩阵快速幂)
题目 传送门:QWQ 分析 因为m很小,考虑把所有状态压成m位二进制数. 那么总状态数小于$ 2^5 $. 如果状态$ i $能转移到$ j $,那么扔进一个矩阵,n次方快速幂一下. 答案是对角线之和 ...
- P1357 花园 (矩阵快速幂+ DP)
题意:一个只含字母C和P的环形串 求长度为n且每m个连续字符不含有超过k个C的方案数 m <= 5 n <= 1e15 题解:用一个m位二进制表示状态 转移很好想 但是这个题是用矩阵快速 ...
- 洛谷 P1357 花园
题意简述 一个只含字母C和P的环形串 求长度为n且每m个连续字符不含有超过k个C的方案数 题解思路 由于\(m<=5\)所以很显然状压 但由于\(n<=10^{15}\).可以考虑用矩阵加 ...
随机推荐
- Groovy动态解析
A:前面需要说些什么吗? B:不需要吗? A:需要吗? 解析方式一:通过指定的paths来初始化GroovyScriptEngine //通过指定的paths来初始化GroovyScriptEngin ...
- vue中上传图片至阿里云oss
1.开通阿里云的oss服务这些这里就不多做介绍了 2.登入阿里云的后台管理系统创建一个Bucket 3.在后台管理系统中进入访问控制 4.点击用户管理->新建用户->填写相关信息,就生成了 ...
- jQuery-插入内容-新增内容
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Installing IIS 8 on Windows Server 2012微软官方安装指导
from: https://www.iis.net/learn/get-started/whats-new-in-iis-8/installing-iis-8-on-windows-server-20 ...
- (转)Hashtable与ConcurrentHashMap区别
ConcurrentHashMap融合了hashtable和hashmap二者的优势. hashtable是做了同步的,hashmap未考虑同步.所以hashmap在单线程情况下效率较高.hashta ...
- java 控制台输入
import java . util . Scanner ; public class Test { public static void main(String[] args) { Scanner ...
- tortoise svn中更改用户
1. Open Windows Explorer.2. Right-click anywhere in the window.3. Click TortoiseSVN → Settings.4. Cl ...
- Lua用一维数组存储一个n阶方阵,输出这个方阵的正对角线上的数的和与反对角线上的数的和的差的绝对值。
arr = {, , , , , , , , -} function diagonalDifference(arr) dimesion = math.sqrt(#arr) arr1 = {} sum1 ...
- Linux 查看磁盘或文件夹及文件大小
当磁盘大小超过标准时会有报警提示,这时如果掌握df和du命令是非常明智的选择. df可以查看一级文件夹大小.使用比例.档案系统及其挂入点,但对文件却无能为力. du可以查看文件及文件夹的大小. ...
- 向SQL Server中导入Excel的数据
1. 手动界面导入Excel数据 同 https://jingyan.baidu.com/article/ce09321b9a0e252bff858ff9.html 首先打开并登陆sql serve ...