zoukankan      html  css  js  c++  java
  • LG题解 P4910 帕秋莉的手环

    更好的阅读体验?

    Description

    对一个长度为 (n) 的环 (01) 染色,要求相邻两个数之间必须有一个 (1),求方案数。(T) 组询问。

    Solution

    (f_i) 表示长度为 (i) 的环的方案数。

    你发现标签里有斐波那契,然后你准备猜一手结论。

    用脚想一想就能得到 (f_1 = 1)(只有 (1) 这一种方案),(f_2 = 3) (有 (11,01,10) 这三种方案)。然后你想到了斐波那契的递推公式:

    [f_i = f_{i - 1} + f_{i - 2} ]

    你在打草纸上模拟出了 (f_5 = 11)

    并花了 (5min) 用计算器验证了 (f_9 = 76,f_{20} = 15127) 的结果。

    然后你花 (10min) 写了个矩阵快速幂,然后你把它切了。。。

    考虑正确性:

    考虑第 (i) 个位置,如果上个金在 (i-2) 的位置出现,你可以在这里放一个金,如果上个金在 (i-1) 的位置出现,你也可以在这里放一个金。不难发现只有这两种转移是合法的,前 (i-1) 长度的项链的所有合法方案有且仅有这两种情况,所以到当前位置的方案数就是前两个位置的方案数的和。

    这个转移比较套路,矩阵快速幂加速转移即可,如果不懂可以来看一下我写的这篇博客矩阵乘法

    总复杂度为 (O(T imes 2^3 log n))

    Code

    /*
    Work by: Suzt_ilymics
    Problem: 不知名屑题
    Knowledge: 垃圾算法
    Time: O(能过)
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define int long long
    #define orz cout<<"lkp AK IOI!"<<endl
    
    using namespace std;
    const int MAXN = 1e5+5;
    const int INF = 1e9+7;
    const int mod = 1e9+7;
    
    struct Matrix {
        int a[2][2];
        Matrix () { memset(a, false, sizeof a); }
        Matrix operator * (Matrix b) {
            Matrix res;
            for(int i = 0; i < 2; ++i) 
                for(int j = 0; j < 2; ++j) 
                    for(int k = 0; k < 2; ++k) 
                        res.a[i][j] = (res.a[i][j] + a[i][k] * b.a[k][j] % mod) % mod;
            return res;
        }
        Matrix operator ^ (int p) {
            Matrix res, x = *this;
            res.a[0][0] = res.a[1][1] = 1;
            while(p) {
                if(p & 1) res = res * x;
                x = x * x, p >>= 1;
            }
            return res;
        }
    }ans, base;
    
    int read(){
        int s = 0, f = 0;
        char ch = getchar();
        while(!isdigit(ch))  f |= (ch == '-'), ch = getchar();
        while(isdigit(ch)) s = (s << 1) + (s << 3) + ch - '0' , ch = getchar();
        return f ? -s : s;
    }
    
    void Init() {
        ans.a[0][0] = 3, ans.a[0][1] = 1;
        ans.a[1][0] = 0, ans.a[1][1] = 0;
        base.a[0][0] = 1, base.a[0][1] = 1;
        base.a[1][0] = 1, base.a[1][1] = 0;
    }
    
    signed main()
    {
        int T = read();
        while(T--) {
            int n = read();
            if(n == 1) puts("1");
            else if(n == 2) puts("3");
            else {
                Init();
                base = base ^ (n - 2);
                ans = ans * base;
                printf("%lld
    ", ans.a[0][0]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    最短路径问题
    这是我的第一篇博客
    Time Series Anomaly Detection
    R-CNN, Fast R-CNN, Faster R-CNN, Mask R-CNN
    database 学习
    AWS Cloud Practioner 官方课程笔记
    Cassandra commands
    go 语言学习
    [Udemy] ES 7 and Elastic Stack
    第9章 内联函数
  • 原文地址:https://www.cnblogs.com/Silymtics/p/solution-P4910.html
Copyright © 2011-2022 走看看