首页 > 技术文章 > 【NOIP 模拟题】求和 (打表找规律+递推)

lris-searching 2016-08-26 20:50 原文

求和

【题目描述】求:1b+2b+3b++ab的和除以10000的余数。
【输入文件】
第一行一个正整数N,表示共有N组测试数据;
接下来N行,每行两个正整数a和b。
【输出文件】 共N行,每行一个对应的答案。
【样例输入】
1
2 3
【样例输出】
9

【题解】【打表找规律+递推】
【因为需要模的数较小,又根据mod的运算规律,可以把所有大于10000的数先Mod再进行乘方和加法运算,这样大于10000的数也都变成小于等于10000的数了,就可以减少循环的长度。】

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int const mod=10000;
ll sum;
int ans[110],n,a,b;
inline void slove1(int n)
{
    ll sum=(1+n)%mod;
    sum=sum*n; sum/=2;
    printf("%lld\n",sum%mod);
    return;
}
inline ll poww(int x,int p)
{
    ll ans=1;
    while(p)
     {
        if(p&1) ans*=x,ans%=mod;
        x*=x; x%=mod; p>>=1;
     }
    return ans%mod;
}
int main()
{
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    int i,j;
    scanf("%d",&n);
    while(n)
     {
        scanf("%d%d",&a,&b);
        if(b==1) {slove1(a%mod); n--; continue;}
        int m=a/mod,md=a%mod;
        if(!m||(m==1&&!md)) 
         {
            sum=1;
            for(i=2;i<=a;++i) 
             if(i==10||i==100||i==1000||i==10000) continue;
              else sum+=poww(i,b),sum%=mod;
            printf("%lld\n",sum);
            n--; continue;
          }
        sum=1*m;
        for(i=2;i<=9999;++i)
         if(i==10||i==100||i==1000) continue;
          else sum+=m*poww(i,b),sum%=mod;
        if(md)
         {
            sum++;
            for(i=2;i<=md;++i)
             if(i==10||i==100||i==1000) continue;
              else sum+=poww(i,b),sum%=mod;
         }
        printf("%lld\n",sum);
        n--;
     }
}

推荐阅读