• BZOJ2326 [HNOI2011]数学作业(分块矩阵快速幂)


    题意:

    定义函数Concatenate (1 ..N)是将所有正整数 1, 2, …, N 顺序连接起来得到的数,如concatenate(1..5)是12345,求concatenate(1...n)%m的值

    思路:

     矩阵快速幂,公式为

    $$
    left[
    egin{matrix}
    f(n)\n\1
    end{matrix}
    ight]=
    left[
    egin{matrix}
    10^k&1&1\
    0&1&1\
    0&0&1
    end{matrix}
    ight]
    left[
    egin{matrix}
    f(n-1)\n-1\1
    end{matrix}
    ight]
    $$

    其中$10^k$可以分快处理,分n为0~9,10~99,100~999等

    代码:

    /**************************************************************
        Problem: 2326
        User: wrjlinkkkkkk
        Language: C++
        Result: Accepted
        Time:64 ms
        Memory:1292 kb
    ****************************************************************/
     
    #include<iostream>
    #include<iomanip> 
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
    #include<list>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mp(a,b) make_pair(a,b)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x)) 
    #pragma Gcc optimize(2)
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
     
    const int maxn = 10000 + 100;
    const int maxm = 5e3 + 100;
    const double eps = 1e-10;
    const int inf = 0x3f3f3f3f;
    const double pi = acos(-1.0);
    int scan(){
        int res=0,ch,flag=0;
        if((ch=getchar())=='-')
            flag=1;
        else if(ch>='0'&&ch<='9')
            res=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')
            res=res*10+ch-'0';
        return flag?-res:res;
    }
     
    ll n, m;
     
    ll mul(ll x,ll y){
        ll s=0;
        while(y)
        {
            if(y&1)s=(s+x)%m;
            x=(x<<1)%m;
            y>>=1;
        }
        return s;
    }
    void mtpl(ll a[4][4], ll b[4][4],ll s[4][4]){
        ll tmp[4][4];
        for(int i = 1; i <= 3; i++){
            for(int j = 1; j <= 3; j++){
                tmp[i][j]=0;
                for(int k = 1; k <= 3; k++){
                    tmp[i][j] += mul(a[i][k] , b[k][j])%m;
                }
                 
            }
             
        }
        for(int i = 1; i <= 3; i++){
            for(int j = 1; j <= 3; j++){
                s[i][j] = tmp[i][j];
            }
        }
        return;
    }
    ll b[4][4];
    void Fast_power(ll t,ll last){
        ll a[4][4];
        mem(a, 0);
        a[1][1] = t;
        a[2][1] = a[3][1] = a[2][2] = a[3][2] = a[3][3] = 1;
        ll y = last-t/10+1;
        while(y){
            if(y & 1) mtpl(b, a, b);
            mtpl(a, a, a);
            y >>= 1;
        }
        //prt(ans);
        return;
    }
    int main(){
     
        scanf("%lld %lld", &n, &m);
     
         
        mem(b, 0);
        for(int i = 1; i <= 3; i++)b[i][i] = 1;
        ll t = 10;
        while(t <= n){
            Fast_power(t, t-1);
            t*=10;
             
        }
        Fast_power(t,n);
        printf("%lld", b[3][1]%m);
        return 0;
    }
    /*
    8 3287492749272074
    */
  • 相关阅读:
    HDU 5438 Ponds
    [HNOI2013]比赛
    [HNOI2009]最小圈
    【模板】高斯消元法
    控制公司 Controlling Companies
    sdut 2878 圆圈
    滑雪
    [ZJOI2010]排列计数
    [HNOI2003]激光炸弹
    [BZOJ 3732]Network
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/9468347.html
Copyright © 2020-2023  润新知