zoukankan      html  css  js  c++  java
  • luogu1397 [NOI2013]矩阵游戏 (等比数列求和)

    一个比较显然的等比数列求和,但有一点问题就是n和m巨大..

    考虑到他们是在幂次上出现,所以可以模上P-1(费马小定理)

    但是a或c等于1的时候,不能用等比数列求和公式,这时候就要乘n和m,又要变成模P

    所以我们一开始就模P*(P-1)好了...

    很大,要用龟速乘

     1 #include<bits/stdc++.h>
     2 #define CLR(a,x) memset(a,x,sizeof(a))
     3 #define MP make_pair
     4 using namespace std;
     5 typedef long long ll;
     6 typedef unsigned long long ull;
     7 typedef pair<int,int> pa;
     8 const int maxn=1;
     9 const ll P=1e9+7,PP=P*(P-1);
    10 
    11 inline ll fmul(ll x,ll y){
    12     ll re=0;
    13     while(y){
    14         if(y&1) re=(re+x)%PP;
    15         x=(x+x)%PP,y>>=1;
    16     }return re;
    17 }
    18 
    19 inline ll rd(){
    20     ll x=0;char c=getchar();int neg=1;
    21     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    22     while(c>='0'&&c<='9') x=(fmul(x,10)+c-'0')%PP,c=getchar();
    23     return x*neg;
    24 }
    25 
    26 inline ll fpow(ll x,ll y){
    27     ll re=1;
    28     while(y){
    29         if(y&1) re=re*x%P;
    30         x=x*x%P,y>>=1;
    31     }
    32     return re;
    33 }
    34 
    35 int main(){
    36     // freopen("testdata.in","r",stdin);
    37     ll n=(rd()-1+PP)%PP,m=(rd()-1+PP)%PP,a=rd(),b=rd(),c=rd(),d=rd();
    38     ll e=fpow(a,m),f;
    39     if(a!=1) f=(e-1)*fpow(a-1,P-2)%P*b%P;
    40     else f=m%P*b%P;
    41     ll g=e*c%P,h=(f*c%P+d)%P;
    42     ll i=fpow(g,n),j;
    43     if(g!=1) j=(i-1)*fpow(g-1,P-2)%P*h%P;
    44     else j=n%P*h%P;
    45     printf("%lld
    ",((e*(i+j)+f)%P+P)%P);
    46     return 0;
    47 }
  • 相关阅读:
    Redis常见数据类型
    MYSQL常见可优化场景
    算术切片
    找数组里没出现的数
    不同路径和(II)
    不同路径和
    最小路径和
    强盗抢房子
    丑数(2)
    判断子序列
  • 原文地址:https://www.cnblogs.com/Ressed/p/10066556.html
Copyright © 2011-2022 走看看