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 }  

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

    > 别忘了 总有人在等着你
  • 相关阅读:
    CodeForces 681D Gifts by the List (树上DFS)
    UVa 12342 Tax Calculator (水题,纳税)
    CodeForces 681C Heap Operations (模拟题,优先队列)
    CodeForces 682C Alyona and the Tree (树上DFS)
    CodeForces 682B Alyona and Mex (题意水题)
    CodeForces 682A Alyona and Numbers (水题,数学)
    Virtualizing memory type
    页面跳转
    PHP Misc. 函数
    PHP 5 Math 函数
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/9930336.html
Copyright © 2011-2022 走看看