zoukankan      html  css  js  c++  java
  • bzoj3328 PYXFIB

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3328

    【题解】

    真心巧妙。

    这个式子看起来不大好,稍作化简。

    斐波那契数列第n项是斐波那契矩阵的n次方的左上角的数。

    化成矩阵形式。

    考虑二项式定理的矩阵形式。

    就差一个[i mod k = 0]不对了,我们就需要构造一个式子,使得当i mod k = 0的时候该式子为1,否则为0.

    考虑单位根,原根。

    令g为原根,那么单位根w=g^((n-1)/k),且题目保证了k|n-1。

    那么对于i属于[0,k-1],当且仅当i=0的时候,w^i=1。

    那么构造

    这个式子当i mod k=0的时候,w^i=k,否则为0.

    进一步,除以一个k就能完成要求了。

    然后我们将这个代入ans。

    我们设B为答案矩阵,B[1,1]即为ans,那么

    稍加转换

    提前sigma,交换位置

    那么我们构造

    观察形式,那么答案就是

    我们枚举k,然后快速幂计算F即可。

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    
    # define RG register
    # define ST static
    
    ll n;
    int k, mod;
    int g, w, inv, ans;
    
    struct mat {
        int a, b, c, d;
        friend mat operator * (mat a, mat b) {
            mat c;
            c.a = (1ll * a.a * b.a + 1ll * a.b * b.c) % mod;
            c.b = (1ll * a.a * b.b + 1ll * a.b * b.d) % mod;
            c.c = (1ll * a.c * b.a + 1ll * a.d * b.c) % mod;
            c.d = (1ll * a.c * b.b + 1ll * a.d * b.d) % mod;
            return c;
        }
        friend mat operator ^(mat a, ll b) {
            mat ret = a; --b;
            while(b) {
                if(b&1) ret = ret * a;
                a = a * a; 
                b >>= 1;
            }
            return ret;
        }
    }A;
    
    inline int pwr(int a, ll b) {
        int ret = 1;
        while(b) {
            if(b&1) ret = 1ll * ret * a % mod;
            a = 1ll * a * a % mod;
            b >>= 1;
        }
        return ret;
    }
    
    int y[M], yn; 
    inline int G() {
        yn = 0;
        int t = mod-1;
        for (int i=2; i*i<=t; ++i) {
            if(t%i == 0) {
                y[++yn] = i;
                if(i*i != t) y[++yn] = t/i;
            }
        }
        bool gg = 0;
        int g = 2;
        while(1) {
            gg = 0;
            for (int i=1; i<=yn; ++i)
                if(pwr(g, y[i]) == 1) {
                    gg = 1;
                    break;
                }
            if(!gg) return g; 
            ++g;
        }
    }
    
    inline int F(int x) {
        A.a = x+1, A.b = A.c = 1, A.d = x;
        A = A ^ n;
        x = pwr(x, mod-2);
        x = pwr(x, n);
        return 1ll * x * A.a % mod;
    }
    
    void sol() { 
        cin >> n >> k >> mod;
        
        g = G(); 
        w = pwr(g, (mod-1)/k);
        inv = pwr(w, mod-2);
        ans = 0;
    //    cout << w << endl;
        
        for (int i=0, x=1; i<k; ++i, x = 1ll * x * inv % mod) {
            ans = ans + F(x);
            if(ans >= mod) ans -= mod;
        }
        
        ans = 1ll * ans * pwr(k, mod-2) % mod;
        ans = (ans + mod) % mod; 
        cout << ans << endl;
    }
    
    int main() {
        int T; cin >> T;
        while(T--) sol();
        return 0;
    }
    View Code
  • 相关阅读:
    python json 和 pickle的补充 hashlib configparser logging
    go 流程语句 if goto for swich
    go array slice map make new操作
    go 基础
    块级元素 行内元素 空元素
    咽炎就医用药(慢性肥厚性咽炎)
    春季感冒是风寒还是风热(转的文章)
    秋季感冒 咳嗽 怎么选药
    解决IE浏览器“无法显示此网页”的问题
    常用的 css 样式 记录
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj3328.html
Copyright © 2011-2022 走看看