发现$m$很小,直接状压起来,可以处理出一开始的合法的状态。

对于每一个合法的状态,可以处理出它的转移方向,即在后面填一个$1$或者填一个$0$,反着处理比较方便。

考虑一下环的情况,在这题中有一个小$trick$就是我们从一个状态$s$开始转移,转移$n$轮到达$n + m$位的情况,这样子只要计算它转移回自身的方案数就一定是合法的。

这样子就可以写方程了。设$f_{i, s}$表示到第$i$位后$m$位是$s$的方案数,这样子有$f_{i, s} = \sum f_{i - 1, s'}$   $s'$可以转移到$s$。

到这里时间复杂度变成了$O((n + m) * 2^m*2^m)$,可以通过$80$分的数据。

发现这一个转移的式子是矩阵乘法的形式,那么对于两个可以转移的状态$s'$和$s$,直接把转移矩阵中$f$的$f_{s', s}$记为$1$。

时间复杂度变成了$O(2^{3m} * logn)$,可以通过全部的数据。

Code:

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll; const int M = ;
const int S = << M;
const ll P = 1e9 + ; int m, K, maxS;
ll n, ans = ;
bool ok[S]; inline int min(int x, int y) {
return x > y ? y : x;
} struct Matrix {
int len, wid;
ll s[S][S]; inline void init() {
memset(s, 0LL, sizeof(s));
len = wid = ;
} friend Matrix operator * (const Matrix u, const Matrix v) {
Matrix res; res.init();
for(int i = ; i < u.len; i++)
for(int j = ; j < v.wid; j++)
for(int k = ; k < u.wid; k++)
res.s[i][j] = (u.s[i][k] * v.s[k][j] % P + res.s[i][j]) % P;
res.len = u.len, res.wid = v.wid;
return res;
} inline Matrix pow(ll y) {
Matrix res, x = *this; res.init();
res.len = x.len, res.wid = x.wid;
for(int i = ; i < min(res.len, res.wid); i++) res.s[i][i] = 1LL;
for(; y > ; y >>= ) {
if(y & ) res = res * x;
x = x * x;
}
return res;
} } f; int main() {
scanf("%lld%d%d", &n, &m, &K);
maxS = << m;
for(int i = ; i < maxS; i++) {
int cnt = ;
for(int tmp = i; tmp > ; cnt += (tmp & ), tmp >>= );
if(cnt <= K) ok[i] = ;
} f.init(), f.len = f.wid = maxS;
for(int i = ; i < maxS; i++)
if(ok[i]) {
f.s[i >> ][i] = ;
f.s[(i >> ) + ( << (m - ))][i] = ;
}
f = f.pow(n); Matrix now;
for(int i = ; i < maxS; i++) {
if(!ok[i]) continue;
now.init(); now.len = , now.wid = maxS, now.s[][i] = 1LL;
now = now * f;
(ans += now.s[][i]) %= P;
} printf("%lld\n", ans);
return ;
}

Luogu 1357 花园的更多相关文章

  1. luogu P1357 花园

    传送门 先考虑朴素dp,设\(f_{i,j}\)表示推了\(i\)次,前\(m\)个点的状态为二进制数\(j\)(这里记放C为1),转移的时候枚举下一位放什么,还要考虑是否满足C的个数\(\leq k ...

  2. 【题解】Luogu P1357 花园

    原题传送门 我们先将花圃断环为链,并将\([1,m]\)复制一份到\([n+1,n+m]\),最后要求\([1,n+m]\)是合法序列且\([1,m]\)与\([n+1,n+m]\)相等的序列的数量即 ...

  3. [luogu]P1133 教主的花园[DP]

    [luogu]P1133 教主的花园 ——!x^n+y^n=z^n 题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会 ...

  4. 【Luogu】U16325小奇的花园(树链剖分)

    题目链接 学了学动态开点的树链剖分,其实跟动态开点的线段树差不多啦 查询的时候别ssbb地动态开点,如果没这个点果断返回0就行 只要注意花的种类能到intmax就行qwq!!!! #include&l ...

  5. 【Luogu】P3313旅行(树链剖分)

    题目链接 动态开点的树链剖分qwq. 跟小奇的花园一模一样,不做过多讲解. #include<cstdio> #include<cstring> #include<cct ...

  6. luogu P2056 采花

    题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 1-c 表示) ,且花是排成 ...

  7. 洛谷—— P1133 教主的花园

    https://www.luogu.org/problem/show?pid=1133 题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都 ...

  8. [COJ2201][KOJ0223][KOJ0250]花园

    [KOJ0223][KOJ0250]花园 试题描述 小奇的花园有n个温室,标号为1到n,温室以及以及温室间的双向道路形成一棵树. 每个温室都种植着一种花,随着季节的变换,温室里的花的种类也在不断发生着 ...

  9. Luogu 魔法学院杯-第二弹(萌新的第一法blog)

    虽然有点久远  还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题  沉迷游戏,伤感情 #include <queue> ...

随机推荐

  1. FMDB的操作(转),这篇比我写的好

    直接看吧 http://blog.devtang.com/blog/2012/04/22/use-fmdb/

  2. Rational Rose 2003 下载、破解及安装方法(图文)

    方法一: 1. 安装Rational Rose2003时,在需选择安装项的时候,只选择Rational Rose EnterPrise Edition即可,不需选择其他项,之后选择“DeskTop I ...

  3. PHP数据结构之实现栈

    接着前面PHP数据结构来学习,今天写的是实现栈. <?php class stack //定义一个栈的类 { private $size; //栈的空间大小 private $top; // 栈 ...

  4. centos7 showdoc 安装部署

    1.进入showdoc官网帮助目录下 https://www.showdoc.cc/web/#/help?page_id=828455960655160 阅读自动安装部署相关事项: 2.利用xshel ...

  5. keepalived之 Keepalived 原理(定义、VRRP 协议、VRRP 工作机制)

    1.Keepalived 定义 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障.一个LVS服务会有2台服务器运行Keepalived,一台为主服务器 ...

  6. 最小LINUX系统下U盘的挂载及卸载

    U盘挂载命令U盘插入的时候会显示启动信息,启动信息中sda: sda1指U盘的设备名为sda1dev设备目录下有一个sda1设备文件,此设备文件就是我们插入的U盘,我们将这个设备文件挂载到Linux系 ...

  7. 【转】 Pro Android学习笔记(八四):了解Package(3):包间数据共享

    目录(?)[-] 共享User ID的设置 共享资源例子 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowing ...

  8. maven jetty 配置

    对于jdk8增加如下配置: <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jett ...

  9. 第九课 go的循环语句

    1 for语句的三种形式 /* for 循环 */ ; a < ; a++ { fmt.Printf("a 的值为: %d\n", a) } var a, b int = 1 ...

  10. Git学习笔记(一)Git初识及基本操作

    详细完整教程:官方文档,廖神Git教程,武sir 一.什么是Git? 定义:Git是分布式版本控制系统. 1.1什么是版本控制 我们可以回想以下,在我们上学毕业要写论文或是准备一份演讲稿的时候,都会用 ...