2014新生暑假个人排位赛final---492. Goblin's Appreciation

本文介绍了一个名为Goblin's Appreciation的比赛题目,该题涉及数学运算及算法优化,通过使用欧拉函数和快速幂算法,在限定时间内解决了大规模数据集的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

时间限制 1000 ms  内存限制 65536 KB

题目描述

    Your clan has been subjected to the harassment of the goblins. Your leader decided to fight back for peace. But the story is more complex than your imagination, reckoning with the numerous resources wasted in the war, the leader assigned you as the envoy to win the dignity.
    Now you have arrived there, you find the goblins love math very much. They only appreciate the guys with high intellegence, so they give you a math problem, if you can solve it in 1s, they will appreciate you and protect your clan as a gift. For peace, just  fighting!
    They give you a lot of pairs of numbers, denoted by K,N. for every input, you should tell them the sum of k^gcd(i,n), for i = 1~n.
    For the answer is so large, you can give them the answer mod 23333.

 

输入格式

Given T, the number of cases. Then, for next T lines, there are two numbers K,N.(1 <= k <= 10^4, 1 <= n <= 10^8)

 

输出格式

For every case, print one line, containing the answer mod 23333.

 

输入样例

3
3 4
2 6
100 50000000

输出样例

96
84
3014



这道题过得太艰辛,当时比赛的时候就想到暴力一定不行,要用欧拉来算,但是没有想到还是超时,今天在大神的各种指导下终于做出来了。

有几个点备注一下提醒自己:

pow太慢而且返回的是double类型。

头文件: math.h/ cmath( C++中)
功能:计算x的y次
返回值:x不能为负数且y为小数,或者x为0且y小于等于0,返回幂指数的结果。
返回类型: double型,int,float会给与警告!

要写快速幂。


#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;//longlong
const int mod=23333;
const int maxn=100000008;
int n;
int ephi(int n)   //欧拉函数,求的是小于n的质因数的个数,这个ephi(n/i)的结果即i为最大公因数的个数。
{
    int res=n;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            res=res/i*(i-1);
            for(;n%i==0;n/=i) ;
        }
    }
    if(n!=1)
        res=res/n*(n-1);
    return res;
}
   
long long mod_pow(long long x,long long n,int mod)   //快速幂,同时取模了。
{
    long long res=1;
    while (n>0)
    {
        if(n&1) res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long ans=0;
        int e;
        long long   n,k;
        scanf("%lld%lld",&k,&n);
        for(int i=1;i*i<=n;i++)  // 注意终止条件,只枚举到sqrt(n),在后面判断。
        {
            if(n%i==0)    //找n的因数
            {
                e=ephi(n/i);
                ans+=e*mod_pow(k,i,mod);
                if(n/i!=i)   //这个地方是关键,由于i是n的因数则n/i也一定是n的因数,可知只要枚举到sqrt即可,然后若因数不重复,则对应地进行一次操作。
                { e=ephi(n/(n/i));
                  ans+=e*mod_pow(k,n/i,mod);
                }
            }
        }
        printf("%lld\n",ans%mod);
    }
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值