【复赛模拟试题】求和 分治+二分快速幂

来源:互联网 发布:数据库客户端如何使用 编辑:程序博客网 时间:2024/06/05 15:41

【问题描述】

  计算 1^b+2^b+…+a^b 的和除以 10000 的余数;

【输入格式】

  第一行一个整数N,表示有N组测试数据;
  接下来N行,每行包含两个正整数a和b。

【输出格式】

  N行,对应输入的答案

【输入样例】

1
2 3

【输出样例】

9

【数据范围】

30%的数据满足:1<=N<=10,a,b<=1000
100%的数据满足:1<=N<=100,a,b<=1000000000

——————————————————————————————————————————————————

问题的解决主要是利用mod=10000。通过这个条件我们发现10001^x%10000=1^x%10000,以此类推。
所以说问题的时间复杂度为O(10000*log2b)。
顺便对比了一下迭代快速幂和递归快速幂的区别,妥妥的递归时间长上一倍(斜眼)。

AC代码:

#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;const int maxn=10005;const int mo=10000;int N,a,b;int C[maxn];int mpow(int x,int y){    int re=1,tt=x;    for(int i=0;(1<<i)<=y;i++)    {        if((1<<i)&y) re=re*tt%mo;        tt=tt*tt%mo;    }    return re;}int main(){    freopen("test.in","r",stdin);    freopen("test.out","w",stdout);    scanf("%d",&N);    C[0]=1;    while(N--)    {        scanf("%d%d",&a,&b);        int upper=min(mo,a),ans=0;        for(int i=1;i<=upper;i++) C[i]=mpow(i,b),ans=(ans+C[i])%mo;        if(a>mo)        {            ans=ans*(a/mo)%mo;            a%=mo;            for(int i=1;i<=a;i++)                ans=(ans+C[i])%mo;        }        printf("%d\n",ans);    }    return 0;}
原创粉丝点击