zoukankan      html  css  js  c++  java
  • Icebound and Sequence(非互质逆元 快速乘法)or(矩阵快速幂)

    Icebound hates math. But Imp loves math. One day, Imp gave icebound a problem. 

    The problem is as follows.

    S=(∑ni=1qi) mod pS=(∑i=1nqi) mod p

    For given q,n,p, you need to help icebound to calculate the value of S.

    输入描述:

    The first line contains an integer T, denoting the number of test cases.
    The next T lines, each line contains three integers q,n,p, separated by spaces. 
    1≤T≤1001≤T≤100, 1≤n,q,p≤1091≤n,q,p≤109

    输出描述:

    For each test case, you need to output a single line with the integer S.

    示例1

    输入

    复制

    2
    2 3 100
    511 4 520

    输出

    复制

    14
    184

    首先有一个基本的公式就是

    a/b%c=a%(b*c)/b

    此公式是用的就是在分母确定时 并且分子很大

    那么我们列出等比数列求和公式

    如果直接×会炸掉long long 那么我们就写一个快速加法进行乘法计算

    #include<bits/stdc++.h>
    using namespace std;
    inline long long  mult_mod(long long a,long long b, long long m)
    {
        long long res = 0;
        while(b){
            if(b&1) res = (res+a)%m;
            a = (a+a)%m;
            b >>= 1;
        }
        return res;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
           long long q,n,p;
           scanf("%lld%lld%lld",&q,&n,&p);
           long long mod=(q-1)*p;
           long long tmppow=1;
           long long tmpq=q;
           if(q==1)
           {
               long long ans=n%p;
               printf("%lld
    ",ans);
               continue;
           }
           while(n)
           {
               if(n%2==1) tmppow=mult_mod(tmppow,tmpq,mod);
               n/=2;
               tmpq=mult_mod(tmpq,tmpq,mod);
           }
           tmppow--;
           if(tmppow<0) tmppow+=mod;
           long long ans=mult_mod(q,tmppow,mod)/(q-1);
           printf("%lld
    ",ans);
        }
    }
    

    对于能写出地推表达式的算式

    我们都可以用矩阵快速幂在logn的时间内解决

    #include<cstdio>
    #include<cstring>
    using namespace std;
    long long q,n,p;
    struct node
    {
        long long a[2][2];
    } pos;
    node milt(node x,node y)
    {
        node res;
        memset(res.a,0,sizeof(res.a));
        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]+x.a[i][k]*y.a[k][j])%p;
        return res;
    }
    long long pow(long long n)
    {
        node x,y;
        x.a[0][0]=1,x.a[0][1]=0,x.a[1][0]=0,x.a[1][1]=1;
        y.a[0][0]=1,y.a[0][1]=1,y.a[1][0]=0,y.a[1][1]=q;
        while(n!=0)
        {
            if(n%2==1) x=milt(x,y);
            y=milt(y,y);
            n/=2;
        }
        long long ans=(x.a[0][1]*q)%p;
        return ans;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%lld%lld%lld",&q,&n,&p);
            printf("%lld
    ",pow(n));
        }
    }
    
  • 相关阅读:
    C# 时间格式化
    新线程匿名方法的新用法
    响应类
    图灵API
    Xpath使用
    Meta http-equiv属性
    CAC的Debian-8-64bit安装BBR正确打开方式
    CAC的Debian-8-64bit安装BBR正确方式是?
    Mbps Mb M Kb如何换算
    如何解决服务器远程桌面连接成功但重启却操作失效?
  • 原文地址:https://www.cnblogs.com/caowenbo/p/11852263.html
Copyright © 2011-2022 走看看