zoukankan      html  css  js  c++  java
  • luogu P1357 花园

    传送门

    神仙题

    首先转化成0/1串没有问题

    然后1的个数有限?限制条件M<=5?

    状压吧孩子

    f[i][S]表示第i位S局面下方案数

    所以可以按照题意转移

    然后转移只和S有关&N<=1e15

    矩阵加速吧孩子

    开一个32*32的矩阵表示状态之间的转移qwq

    (话说错位这个地方想的时间挺长的)

    等下!这是个环?

    难不成要枚举断点

    考虑矩阵里面元素的定义

    m[i][j]^k表示i状态到j状态经过k步的方案数

    所以∑m[i][i]^n(i∈1->32)就是答案

    最终复杂度O(2^5^3*lg(1e15)) 勉强能过

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<queue>
     6 #include<iostream>
     7 #define ms(a,b) memset(a,b,sizeof a)
     8 #define rep(i,a,n) for(int i = a;i <= n;i++)
     9 #define per(i,n,a) for(int i = n;i >= a;i--)
    10 #define inf 2147483647
    11 using namespace std;
    12 typedef long long ll;
    13 #define mod 1000000007
    14 ll read() {
    15     ll as = 0,fu = 1;
    16     char c = getchar();
    17     while(c < '0' || c > '9') {
    18         if(c == '-') fu = -1;
    19         c = getchar();
    20     }
    21     while(c >= '0' && c <= '9') {
    22         as = as * 10 + c - '0';
    23         c = getchar();
    24     }
    25     return as * fu;
    26 }
    27 struct Mt {
    28     const static int M = 64;
    29     ll a[M][M];
    30     void init(int op) {
    31     ms(a,0);
    32     if(op == 1) rep(i,0,M-1) a[i][i] = 1;
    33     }
    34 
    35     Mt operator * (const Mt &o) const {
    36     Mt tmp;tmp.init(0);
    37     rep(i,0,M-1) rep(j,0,M-1) rep(k,0,M-1) {
    38         tmp.a[i][j] = (tmp.a[i][j] + a[i][k] * o.a[k][j] % mod) % mod;
    39     }
    40     return tmp;
    41     }
    42 
    43     Mt operator ^ (ll b) const {
    44     Mt r = *this;
    45     Mt tmp;tmp.init(1);
    46     while(b) {
    47         if((b) & 1) tmp = tmp * r;
    48         r = r * r;
    49         (b) >>= 1;
    50     }
    51     return tmp;
    52     }
    53 }x;
    54 //head
    55 ll n,m,k,ans;
    56 int stat[40];
    57 #define low(x) ((x)&(-(x)))
    58 int judgeI(ll x) {
    59     int tmp = 0;
    60     for(int i = x;i;i -= low(i)) tmp++;
    61     return tmp;
    62 }
    63 
    64 int main() {
    65     n = read(),m = read(),k = read();
    66     int Max = 0;
    67     rep(i,0,(1<<m)-1) 
    68     if(judgeI(i) <= k) stat[++Max] = i;
    69     rep(i,1,Max) rep(j,1,Max) {
    70     int xx = stat[i] % (1<<m-1);
    71     int yy = stat[j] >> 1;
    72     if(xx == yy) {
    73         x.a[stat[i]][stat[j]] = 1;
    74     }
    75     }
    76     x = x ^ (n);
    77     rep(i,1,Max) ans = (ans + x.a[stat[i]][stat[i]]) % mod;
    78     printf("%lld
    ",ans);
    79     return 0;
    80 }  

    最后自己还是能写出来矩阵加速的题还是比较开心的

    > 别忘了 总有人在等着你
  • 相关阅读:
    Spark基本架构及原理
    深度剖析Spark分布式执行原理
    Spark的集群管理器
    基于Redis的开源分布式服务Codis
    RabbitMQ 概念
    分布式事务实现
    优酷 视频上传服务
    深入解析Java中volatile关键字的作用
    mysql in查询 结果乱序 引发的思考
    不安装oracle客户端,用plsql连接oracle
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/9930336.html
Copyright © 2011-2022 走看看