• 快速幂与费马小定理与组合数


    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    #include <vector>
    #include <math.h>
    using namespace std;
    long long int QPow(long long int a,long long int x){
        if(x == 0){return 1;}
        if(x == 1){return a;}
        long long int ans = QPow(a,x / 2);
        if(x % 2 == 0){return ans * ans;}
        return ans * ans * a;
    }
    
    int main(){
        long long int a,b;
        while(scanf("%lld%lld",&a,&b) != EOF){
            long long int ans = QPow(a,b);
            printf("%lld
    ",ans);
        }
        return 0;
    }

    算法时间复杂度O(logN)。

    牛客网WannaFly挑战赛11.B——白兔的式子

    链接:https://www.nowcoder.com/acm/contest/73/B
    来源:牛客网

    题目描述

    已知f[1][1]=1,f[i][j]=a*f[i-1][j]+b*f[i-1][j-1](i>=2,1<=j<=i)。
    对于其他情况f[i][j]=0

    有T组询问,每次给出a,b,n,m,求f[n][m] mod (998244353)

    输入描述:

    第一行为一个整数T,表示询问个数。
    接下来一共T行,每行四个整数a,b,n,m。

    输出描述:

    一共T行,每行一个整数,表示f[n][m] mod (998244353)
    示例1

    输入

    2
    2 3 3 3
    3 1 4 1

    输出

    9
    27

    备注:

    T<=100000

    1<=m<=n<=100000

    0<=a,b<=109

    同余除法,求逆元,费马小定理,快速幂,阶乘预处理

    费马小定理:一个数a,一个质数p。a的逆元是a^(p - 2)。

    AC代码:

    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<cstring>
    #include<math.h>
    using namespace std;
    long long int Mod = 998244353;
    long long int A[200050];
    long long int P[200050];
    
    long long int QPow(long long int a,long long int x){
        if(x == 0){return 1;}
        if(x == 1){return a;}
        long long int ans = QPow(a,x / 2);
        if(x % 2 == 0){return ans * ans % Mod;}
        return ans * ans % Mod * a % Mod;
    }
    
    void init(){
        A[0] = 1;
        A[1] = 1;
        for(int i = 2;i <= 200000;i ++){
            A[i] = i * A[i - 1] % Mod;
        }
        P[0] = 1;
        P[100000] = QPow(A[100000],Mod - 2);
        for(int i = 99999;i >= 1;i --){
            P[i] = P[i + 1] * (i + 1) % Mod;
        }
    }
    
    int main()
    {
        int T;
        init();
        scanf("%d",&T);
    
        while(T --){
            long long int a,b,n,m;
            scanf("%lld%lld%lld%lld",&a,&b,&n,&m);
            if(m > n){printf("0
    ");}
            else{
                long long int ans = A[n - 1] * P[m - 1] % Mod * P[n - m] % Mod * QPow(a,n - m) % Mod * QPow(b,m - 1) % Mod;
                printf("%lld
    ",ans);
            }
    /*
            printf("%lld
    ",A[n - 1]);
            printf("%lld
    ",QPow(A[m - 1],Mod - 2));
            printf("%lld
    ",QPow(A[n - m],Mod - 2));
            printf("%lld
    ",QPow(a,n - m));
            printf("%lld
    ",QPow(b,m - 1));
    */
        }
    
        return 0;
    }

    提交的过程中,一开始将ans分成两部分再乘到一起,WA了无数发,后来放到一起就神奇的过了。不知道为啥= =

    Hrbust 1140

    题目大意:

      给a,b(2000000000以内),求出a^b在进行策略。

      策略为将所有数字加到一起,循环至一位数。

      如12345 = 1+2+3+4+5 = 15 = 1+6 = 7。

    题意分析:

      矩阵快速幂无需多说,重要的是该模多少。

      有一个推论 设 abcde为一个整数,a+b+c+d+e = n,则n%9 = abcde % 9。

      推理如下:

        a + b + c + d + e = 9999a + a + 999b + b + 99c + c + 9d + d + e = abcde。

    AC代码:

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    #include <vector>
    #include <math.h>
    #define llt long long
    using namespace std;
    
    long long int Mod = 9;
    long long int QPow(long long int a,long long int x){
        if(x == 0){return 1;}
        if(x == 1){return a;}
        long long int ans = QPow(a,x / 2);
        if(x % 2 == 0){return ((ans % Mod) * (ans % Mod)) % Mod;}
        return ((ans % Mod) * (ans % Mod) % Mod * a % Mod) % Mod;
    }
    
    int main(){
        long long int a,b;
        while(scanf("%lld%lld",&a,&b) != EOF){
            long long int ans = QPow(a,b);
            if(a == 0){ans = 0;}
            else if(ans == 0){ans = 9;}
            printf("%lld
    ",ans);
        }
    
    
        return 0;
    }
        

    石油大学oj 6016

    题目要求 给n(3,1e9),k(3,1e6),求C(n,k) + ... + C(n,n)。

    因为k<<n,应求2^n - C(n,0) - C(n,1) - ... - C(n,k - 1)。

    主要坑点在于如何处理负数,加上modd再模一次即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    long long int ans = 1;
    long long int modd = 1e9 + 7;
    long long int QPow(long long int a,long long int x){
        if(x == 0){return 1;}
        if(x == 1){return a;}
        long long int ans = QPow(a,x / 2);
        if(x % 2 == 0){return ans * ans % modd;}
        return ans * ans % modd * a % modd;
    }
    
    long long int _p(long long int x){
        return QPow(x,modd - 2);
    }
    
    void C(long long int n,long long int k){
        long long int t1 = n;
        long long int t2 = 1;
        long long int a = n;
        long long int b = 1;
        for(long long int i = 1;i < k;i ++){
            ans = (ans - a * _p(b) % modd + modd) % modd;
            //printf("A %lld
    ",ans);
            //printf("M %lld
    ",a * _p(b) % modd);
            t1 --;t2 ++;
            a = a * t1 % modd;
            b = b * t2 % modd;
            //printf("a %lld
    b %lld
    ",a,b);
        }
    }
    
    int main(){
        long long int n,k;
        while(scanf("%lld%lld",&n,&k)!=EOF){
            if(k > n){printf("0
    ");continue;}
            ans = QPow(2,n) - 1;
            C(n,k);
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    [日志]“著名”炒股实用口诀
    Taven教授:解决失眠的好办法
    [日志]挂在树上的茶壶
    [日志]教你把脉知生男生女
    [日志]看了很多次的十句话
    [健康]国家制定公布甲型流感中药方市民可食用预防
    初学者如何开发出高质量J2EE系统
    学老中医的顺口溜防病
    [健康]巧用药茶疗慢性咽炎
    [日志]说一个人长的丑!如何说?
  • 原文地址:https://www.cnblogs.com/love-fromAtoZ/p/8552053.html
Copyright © 2020-2023  润新知