cf 359c Prime Number

本文介绍了一个计算特定数学表达式的算法,通过计算x的a次方的导数之和,并找出分子与分母的最大公约数,进而简化表达式。采用C++实现,利用哈希表记录每项的次数,特别注意了当次数为x的倍数时的特殊情况。


点击打开链接


题意: 

求x^a,,,, 所有数导数之和,分子,分母的最大公约数。


题解:

sum=a1+a2+a3+......;

其实分母就是x^sum;

分子为  x^sum-a1+x^sum-a2.......;

求出分子的x最小次方就行了。

但是形如  2 2

29 29

2^29 +2^29 =2^30;

所以,当最小次方的个数是x倍数,想上进x倍数次。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <map>
#define LL long long
using namespace std;
const int maxn=1e5+10;
const int mod=1e9+7;
LL a[maxn];
LL calc(LL x,LL y){
    LL ret=1;
    while(y){
        if(y%2==1){
            ret=(ret%mod*x%mod)%mod;
        }
        y/=2;
        x=(x%mod*x%mod)%mod;
    }
    return ret;
}

map<LL,LL>m;
map<LL,LL>::iterator it;
int main(){
    int n,x;
    LL sum=0;
    scanf("%d %d",&n,&x);
    for(int i=0;i<n;++i){
        scanf("%lld",&a[i]);
        sum+=a[i];
    }
    for(int i=0;i<n;++i) {
        a[i]=sum-a[i];
        m[a[i]]++;
    }
    LL num,cnt,ans=sum;
    while(1){
        it=m.begin();
        num=it->first;
        cnt=it->second;
        m.erase(num);
        if(cnt%x>0){
            if(num<sum) ans=num;
            break;
        }
        cnt/=x;
        m[++num]+=cnt;
    }
    printf("%lld\n",calc(x,ans));
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值