• C++之路进阶——codevs1281(Xn数列)


    1281 Xn数列

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 大师 Master
     
     
     
    题目描述 Description

    给你6个数,m, a, c, x0, n, g

    Xn+1 = ( aXn + c ) mod m,求Xn

    m, a, c, x0, n, g<=10^18

    输入描述 Input Description

    一行六个数 m, a, c, x0, n, g

    输出描述 Output Description

    输出一个数 Xn mod g

    样例输入 Sample Input

    11 8 7 1 5 3

    样例输出 Sample Output

    2

    数据范围及提示 Data Size & Hint

    int64按位相乘可以不要用高精度。

    题解:

      1.俄罗斯农夫算法。

      2.矩阵 {(a,0)(1,1)},{Xn,c}

      3.要用快速幂。

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #define ll long long
     4 
     5 using namespace std;
     6 
     7 long long m,a,c,x0,n,g;
     8 long long x[2][2],b[2][2],f[1][2];
     9 
    10 long long mull(long long a,long long b,long long m)
    11      {
    12          long long ans=0;
    13          while (b)
    14            {
    15                if (b&1) ans=(a+ans)%m;
    16                b>>=1;
    17                a=(a<<1)%m; 
    18            }
    19          return ans;  
    20      }
    21 
    22 int mull1 (long long a[2][2],long long b[2][2],long long ans[2][2])
    23      { 
    24         long long c[2][2];
    25          for (int i=0;i<2;i++)
    26             for (int j=0;j<2;j++)
    27              {
    28                  c[i][j]=0;
    29               for (int k=0;k<2;k++)
    30                 c[i][j]=(c[i][j]+mull(a[i][k],b[k][j],m))%m;    
    31               }  
    32           for (int i=0;i<2;i++)
    33             for (int j=0;j<2;j++)
    34             ans[i][j]=c[i][j];    
    35      }
    36 
    37 int mull2 (long long a[1][2],long long b[2][2],long long ans[1][2])
    38      {
    39          long long c[1][2];
    40          for (int i=0;i<1;i++)
    41             for (int j=0;j<2;j++)
    42                {
    43                    c[i][j]=0;
    44                    for (int k=0;k<2;k++)
    45                    c[i][j]=(c[i][j]+mull(a[i][k],b[k][j],m))%m;
    46                }
    47            for (int i=0;i<2;i++)
    48              ans[0][i]=c[0][i];    
    49      }
    50      
    51 int main()
    52    {
    53         scanf("%lld%lld%lld%lld%lld%lld",&m,&a,&c,&x0,&n,&g);
    54         x[0][0]=a;
    55      x[1][0]=x[1][1]=1;
    56      b[0][0]=b[1][1]=1;
    57      f[0][0]=x0;f[0][1]=c;
    58      while (n)
    59        {
    60             if (n&1) mull1(x,b,b);
    61               mull1(x,x,x);
    62               n>>=1;
    63        }
    64        mull2(f,b,f);
    65        printf("%lld
    ",f[0][0]%g);       
    66         return 0;
    67    }
  • 相关阅读:
    Linux 安装中文man手册
    centos6.9使用NTFS-3G挂载ntfs文件系统
    Linux基础知识之挂载详解(mount,umount及开机自动挂载)
    技术点总结
    SQL 分组后获取其中一个字段最大值的整条记录 【转载】
    线程池之ThreadPool类与辅助线程
    Task.Run使用默认线程池
    VS生成事件
    线程池之ThreadPoolExecutor使用
    Sql笔记
  • 原文地址:https://www.cnblogs.com/grhyxzc/p/5191346.html
Copyright © 2020-2023  润新知