• 【快速幂+中等难度】Calculation 哈工大HITOJ2901


    这些天好颓啊。。都没有A题,只是各种等着填的坑。。简直、、

    这道题。。。。其实是快速幂模板题。。为了学习矩阵快速幂,顺手复习下快速幂。。。

    哈工大的OJ其实还挺友好的。速度也快。。赞一个。。

    翻译

              给你两个数A,B,要你求(1b + 2b + ... + ab) 这个式子mod a的结果。(b是奇数)

              每行一组数据

              (我以下的代码和解释都是用大写的A,B来代替原题小写a,b,代码中的小写a只是一个类似tmp的东西)

    原题

    http://acm.hit.edu.cn/hoj/problem/view?id=2901

    Given two integers a and b, you are to calculate the value of the following expression: (1b + 2b + ... + ab) modulo a.

    Note that b is an odd number.

    Input specifications

    Each line of input consists of two integers a and b (1≤a≤1000000000, 1≤b≤1000000000) respectively.

    Output specifications

    For each case of input, you should output a single line, containing the value of the expression above.

    Sample Input

    1 1
    2 1
    

    Sample Output

      0

      1


    思路

       快速幂模板题。

       中等难度是因为有一个人类根本YY不出来的优化:(我偷偷看了看题解。。)

            根据二项式展开,发现  [ c^b+(a-c)^b ] % a = 0 ,所以有:

                    若a为奇数,答案为0,若a为偶数,答案为a/2的b次方(快速幂)  还要%a。。

       下面给个人类的推导过程:

       

       

        一定是发现了什么不得了的东西:当我们把第i项和第A-i项的结果相加,刚好会被A整除。。所以。。

        只有偶数的一半那个(如上图12的一半6)只有两个自己相加。。而实际上没有两个同样的项,那么我们要输出的就是它的快速幂结果。。

        所以:奇数:0,偶数:((A/2)^B)%A;

        这样我们成功把复杂度降到了O(n)左右。。(如果出题人太坑也没办法,事实证明没有这么坑)

        这里以上的证明都是针对B为奇数的特例,如果B为偶数则以上式子均不适用

        (如果A,B均为偶数,则第i项与第A-i+1项的和会呈现对称分布。。(或者说第i项与第A-i项的和们最后一项是0,前面的呈现对称分布),

         而若A为奇数,B为偶数,第i项与第A-i(+1)项的和会很奇怪。。我也没找到规律。。)

    注意

       一个数的奇偶性可以用&1来判断,即若(P&1)==1则表示P为奇数,若(P&1)==0则表示P为偶数

    当然,这只是一个优化常数的方法。。如果没有把握还是用%2吧。。

    代码

    /*http://acm.hit.edu.cn/hoj/problem/view?id=2901*/
    
    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    long long A,B;
    
    inline int read()
    {
        long long x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    
    struct pointer
    {
        long long AA,BB;
    };
    
    long long Matrix_multiplication(long long a, long long n)
    {
        long long ret = 1;
        while(n)
        {
            if(n&1) ret = (ret*a)%A;
            a = (a*a)%A;
            n >>= 1;
        }
        return ret;
    }
    
    int main()
    {
        long long times,ans;
        while( cin>>A>>B )
        {
        ans=0;
            if ((A&1)==0)
            {
              ans=Matrix_multiplication(A/2,B);
              ans%=A;
            }
            else 
            {
                ans=0;
            }
        cout<<ans<<endl;
    }
        return 0;
    }

    结果

           

    noip忘记取模的痛
  • 相关阅读:
    vue-cli3使用cdn引入
    修饰器
    go strconv
    【BZOJ 5125】小Q的书架
    【NOI 2009】诗人小G
    后缀数组
    点分治
    四边形不等式
    【NOIP 2015】Day2 T3 运输计划
    【NOIP 2016】Day1 T2 天天爱跑步
  • 原文地址:https://www.cnblogs.com/seekdreamer/p/3854311.html
Copyright © 2020-2023  润新知