luogu P1357 花园

题目链接

luogu P1357 花园

题解

开始读错题了,QAq,只看了m<=n,然后这怎je做啊QAq
用一种可行状态做环的起始部分,维护后m个的状态,进行装压dp,在后边插可行状态,那么如何保证环呢 ,
由于是环,所以转移n次后,贡献有用的方案是,末装态与原来相同的方案 ,(也就是末状态转移为初状态的方案) 当然,状态必须在满足条件的状态中转移 ->80pts
对于转移矩阵,矩阵快速幂优化装态转移的递推 ->100pts
那么状态S答案为矩阵[S][S]的值

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
const int mod = 1000000007;
LL n,m,k,S;
const int maxs = (1 << 5) + 7;
struct Matrix {
    LL a[maxs][maxs];
    Matrix(){memset(a,0,sizeof a); }
    Matrix operator * (const Matrix & x) const {
        Matrix ret;
        for(int k = 0;k <= S;++ k)
            for(int i = 0;i <= S;++ i)
                for(int j = 0;j <= S;++ j)
                    ret.a[i][j] = (ret.a[i][j] + a[i][k] * x.a[k][j]) % mod;
        return ret;
    }
} t,ans;
bool can[maxs];
void connect(int s,int num) {
    can[s] = 1;int pre = s >> 1;
    t.a[pre][s] = 1;
    if(num == k && !(s & 1)) return;
    t.a[pre | (1 << (m - 1))][s] = 1;
}
void dfs(int x,int num,int s) {
    if(x == m + 1) {connect(s,num);return;}
    dfs(x + 1,num,s);
    if(num < k) dfs(x + 1,num + 1,s | (1 << (x - 1))) ;
}
void qpow() {
    for(int i = 0;i <= S;++ i) ans.a[i][i] = 1;
    for(;n;n >>= 1,t = t * t)
        if(n & 1) ans = ans * t;
}
int main()  {
    scanf("%lld%lld%lld",&n,&m,&k);
    S = (1 << m) - 1;
    dfs(1,0,0);
    qpow();
    LL Ans = 0;
    for(int i = 0;i <= S;++ i) if(can[i])Ans = (Ans + ans.a[i][i]) % mod;
    printf("%lld\n",Ans);
    return 0;
} 

原文地址:https://www.cnblogs.com/sssy/p/9265324.html

时间: 2024-10-17 13:32:22

luogu P1357 花园的相关文章

【题解】Luogu P1357 花园

原题传送门 我们先将花圃断环为链,并将\([1,m]\)复制一份到\([n+1,n+m]\),最后要求\([1,n+m]\)是合法序列且\([1,m]\)与\([n+1,n+m]\)相等的序列的数量即可 \(m\)很小,珂以考虑状压,\(C\)是\(0\),\(P\)是\(1\),可以将长\(m\)的花圃压缩成一个数 我们先考虑\([1,m]\)的可行方法,直接暴力预处理 如何从\([1,m]\)转移到\([2,m+1]\):设\([1,m]\)的状态为\(a\),我们珂以将第一个数字删掉再在最

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 由于请

P1357 花园

[数据规模] 40%的数据中,N<=20: 60%的数据中,M=2: 80%的数据中,N<=10^5. 100%的数据中,N<=10^15. 看到这个数据范围,我首先想到的是80分的写法 80分的写法可以使用状压DP f[i][j]表示第i位,前m个二进制状态为j有多少种方式 t1=(j>>1)|(1<<(m-1)); t2=j>>1; 转移到下一位有两种选择 t1为选C花圃,t2为选P花圃 当然如果选t1则超过k个C花圃,则不可转移 if(ji[t1

P1357 花园 (矩阵快速幂+ DP)

题意:一个只含字母C和P的环形串 求长度为n且每m个连续字符不含有超过k个C的方案数 m <= 5  n <= 1e15 题解:用一个m位二进制表示状态 转移很好想 但是这个题是用矩阵快速幂加速dp的 因为每一位的转移都是一样的 用一个矩阵表示状态i能否转移到状态j 然后跑一遍 初试模板题 #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod = 1e9 + 7; ll n,

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

题目链接 学了学动态开点的树链剖分,其实跟动态开点的线段树差不多啦 查询的时候别ssbb地动态开点,如果没这个点果断返回0就行 只要注意花的种类能到intmax就行qwq!!!! #include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<cstdlib> #include<map> #define mid ((l+r)>>

luogu P2056 采花

题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 1-c 表示) ,且花是排成一排的,以便于公主采花. 公主每次采花后会统计采到的花的颜色数, 颜色数越多她会越高兴! 同时, 她有一癖好,她不允许最后自己采到的花中,某一颜色的花只有一朵.为此,公主每采一朵花,要么此前已采到此颜色的花,要么有相当正确的直觉告诉她,她必能再次采到此颜色的花. 由于时间关系,公主只能走过花园连续的

洛谷1133 教主的花园

洛谷1133 教主的花园 本题地址:http://www.luogu.org/problem/show?pid=1133 题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价值. 教主最喜欢3种树,这3种树的高度分别为10,20,30.教主希望这一圈树种得有层次感,所以任何一个位置的树要比它相邻的两棵树的高度都高或者都低,并且在此条件下,教主想要你设计出一套方案,使得观赏价值之和最

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

题目链接 动态开点的树链剖分qwq. 跟小奇的花园一模一样,不做过多讲解. #include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<algorithm> #define maxn 100010 #define mid ((l+r)>>1) #define check(x) if(x==0) x=++tot; using namespa

luogu P3799 妖梦拼木棒

二次联通门 : luogu P3799 妖梦拼木棒 /* luogu P3799 妖梦拼木棒 用一个桶存下所有的木棒 美剧两根短的木棒长度 后随便乘一乘就 好了.. */ #include <algorithm> #include <cstdio> #define Mod 1000000007 #define Max 5000 void read (int &now) { now = 0; register char word = getchar (); while (wo