CodeForces 17 D.Notepad(指数循环定理)

本文介绍了一种基于大数基数的排序算法实现方法,通过利用指数循环定理和快速幂运算来解决大基数下长数字的排序问题,尤其是在计算最后一页有多少个数字这一特定场景中。

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

Description

把所有b进制无前导0的长度为n的数字写在本子上,一页c个,问最后一页有多少个

Input

三个正整数b,n,c(2b<10106,1n<10106,1c106)

Output

输出最后一页上的数字个数

Sample Input

2 3 3

Sample Output

1

Solution

答案即为(b1)bn1 mod cn很大,要用到指数循环定理,即AB mod C=AB mod ϕ(C)+ϕ(C) mod C(Bϕ(C)) ,对于n1<ϕ(c)的情况直接快速幂即可,注意模完是0答案是c

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=1000005;
char b[maxn],n[maxn];
ll c;
int phi(int n)
{
    int ans=n;
    for(int i=2;i*i<=n;i++)
        if(n%i==0)
        {
            ans=ans/i*(i-1);
            while(n%i==0)n/=i;
        }
    if(n>1)ans=ans/n*(n-1);
    return ans;
}
int Deal(char *s,int mod)
{
    int ans=0,len=strlen(s);
    for(int i=0;i<len;i++)ans=(10ll*ans+s[i]-'0')%mod;
    return ans;
}
int mod_pow(int a,int b,int c)
{
    int ans=1;
    while(b)
    {
        if(b&1)ans=(ll)ans*a%c;
        a=(ll)a*a%c;
        b>>=1;
    }
    return ans;
}
int main()
{
    while(~scanf("%s%s%d",b,n,&c))
    {
        int x=Deal(b,c),y,z;
        int len=strlen(n);
        if(len<10)
        {
            y=0;
            for(int i=0;i<len;i++)y=10*y+n[i]-'0';
            y--;
        }
        else y=Deal(n,phi(c))-1+phi(c);
        z=(x+c-1)%c;
        int ans=(ll)z*mod_pow(x,y,c)%c;
        if(ans==0)ans=c;
        printf("%d\n",ans);
    }
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值