Codeforces 17D Notepad 简单数论

由题意可知,anw =  (b-1)*b^(n-1)%c,则重点为求b^(n-1)。

弱渣推不出来只能上公示。

phi(c)为小于c且与c互质的个数。

当x >= phi(c)时:A^x = A(x%phi(c) + phi(c)) 。

当x < phi(c)时:直接求即可。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <ctime>
#include <iomanip>

#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-6)
#define _LL long long
#define ULL unsigned long long
#define LL __int64
#define INF 0x3f3f3f3f
#define Mod 1000000007

/** I/O Accelerator Interface .. **/
#define g (c=getchar())
#define d isdigit(g)
#define p x=x*10+c-'0'
#define n x=x*10+'0'-c
#define pp l/=10,p
#define nn l/=10,n
template<class T> inline T& RD(T &x)
{
    char c;
    while(!d);
    x=c-'0';
    while(d)p;
    return x;
}
template<class T> inline T& RDD(T &x)
{
    char c;
    while(g,c!='-'&&!isdigit(c));
    if (c=='-')
    {
        x='0'-g;
        while(d)n;
    }
    else
    {
        x=c-'0';
        while(d)p;
    }
    return x;
}
inline double& RF(double &x)      //scanf("%lf", &x);
{
    char c;
    while(g,c!='-'&&c!='.'&&!isdigit(c));
    if(c=='-')if(g=='.')
        {
            x=0;
            double l=1;
            while(d)nn;
            x*=l;
        }
        else
        {
            x='0'-c;
            while(d)n;
            if(c=='.')
            {
                double l=1;
                while(d)nn;
                x*=l;
            }
        }
    else if(c=='.')
    {
        x=0;
        double l=1;
        while(d)pp;
        x*=l;
    }
    else
    {
        x=c-'0';
        while(d)p;
        if(c=='.')
        {
            double l=1;
            while(d)pp;
            x*=l;
        }
    }
    return x;
}
#undef nn
#undef pp
#undef n
#undef p
#undef d
#undef g
using namespace std;

char s[1000010];
int B[1000010],N[1000010];
LL c,b,n;

bool vis[1000010];
LL prime[1000010];
int Top;

LL Euler(LL n)
{
    LL ret=1,i;
    for(i=2; i*i<=n; i++)
    {
        if(n%i==0)
        {
            n/=i,ret*=i-1;
            while(n%i==0)
                n/=i,ret*=i;
        }
    }
    if(n>1)
        ret*=n-1;
    return ret;
}

LL Cal(int *n,LL c,bool &mark)
{
    LL re = 0;

    for(int i = 0; n[i] != -1; ++i)
    {
        re *= 10,re += n[i];
        if(re >= c)
            mark = true,re %= c;
    }
    return re;
}

LL qm(LL a,LL b,LL n)
{
    LL ret=1;
    LL tmp=a;
    while(b)
    {
        if(b&1) ret=ret*tmp%n;
        tmp=tmp*tmp%n;
        b>>=1;
    }
    return ret;
}

int main()
{
    int i,j;

    scanf("%s",s);
    for(i = 0; s[i] != '\0'; ++i)
        B[i] = s[i]-'0';
    B[i] = -1;

    scanf("%s",s);
    for(i = 0; s[i] != '\0'; ++i)
        N[i] = s[i]-'0';
    N[i] = -1;

    scanf("%I64d",&c);

    LL MAXN = sqrt(c);
    memset(vis,false,sizeof(vis));
    Top = 0;

    for(i = 2; i <= MAXN; ++i)
        if(vis[i] == false)
            for(j = i+i,prime[Top++] = i; j <= MAXN; j += i)
                vis[j] = true;

    LL phi = Euler(c),b1;
    bool mark = false;
    b = Cal(B,c,mark);
    mark = false;
    n = Cal(N,phi,mark);
    b1 = (b-1+c)%c;

    if(mark == true)
        n = (n-1+phi)%phi + phi;
    else
        n--;

    LL anw = b1*qm(b,n,c)%c;

    if(anw == 0)
        anw = c;
    printf("%I64d\n",anw);

    return 0;
}
时间: 2025-01-24 19:21:50

Codeforces 17D Notepad 简单数论的相关文章

Codeforces 17D Notepad 简单的数论

从题意,anw =  (b-1)*b^(n-1)%c,强调,为了b^(n-1). 弱渣只能推了宣传. phi(c)为小于c且与c互质的个数. 当x >= phi(c)时:A^x = A(x%phi(c) + phi(c)) . 当x < phi(c)时:直接求就可以. #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include &l

Codeforces 413B Spyke Chatting(数论简单)

题目链接:Codeforces 413B Spyke Chatting 题目大意:n个人,m种聊天器,k次发送消息,然后给出n*m的矩阵,如果g[i][j]为1,则表示i号人会使用j号聊天器,接着给出k次消息发送者和聊天器,如果i在j种聊天器上发送了一条消息,那么所有使用j种聊天器的人都会接受到消息.现在要求每个人会接受到几条消息,自己发送的不算. 解题思路:分别记录每个聊天器上有多少个消息,以及每个人发送了多少条消息,然后计算每个人接受到多少条消息的时候只要将这个人所使用的各个聊天器消息数取和

[CodeForces - 1225C]p-binary 【数论】【二进制】

[CodeForces - 1225C]p-binary [数论][二进制] 题目描述 Time limit 2000 ms Memory limit 524288 kB Source Technocup 2020 - Elimination Round 2 Tags bitmasks brute force math *1600 Site https://codeforces.com/problemset/problem/1225/c 题面 Example Input1 24 0 Output

hdu 1395 2^x mod n = 1 (简单数论)

题目大意: 求出一个最小的x 使得 2的x次方对n取模为1 思路分析: 若要 a*b%p=1  要使得b存在 则 gcd (a,p)=1. 那么我们应用到这个题目上来. 当n为偶数 2^x 也是偶数,那么gcd 肯定不是1.故这个是不存在的. 那么n为奇数的时候,也就一定是1了. 所以直接暴力找. #include <iostream> #include <cstdio> using namespace std; int main() { int n; while(scanf(&q

Codeforces 41D Pawn 简单dp

题目链接:点击打开链接 给定n*m 的矩阵 常数k 下面一个n*m的矩阵,每个位置由 0-9的一个整数表示 问: 从最后一行开始向上走到第一行使得路径上的和 % (k+1) == 0 每个格子只能向或走一步 求:最大的路径和 最后一行的哪个位置作为起点 从下到上的路径 思路: 简单dp #include <cstdio> #include <algorithm> #include<iostream> #include<string.h> #include &

HDOJ 1163 Eddy&#39;s digital Roots(简单数论)

[思路]:http://blog.csdn.net/iamskying/article/details/4738838 求解思路: 现在分析一个问题,假设将十位数为a,个位数为b的一个整数表示为ab,则推导得 ab*ab = (a*10+b)*(a*10+b) = 100*a*a+10*2*a*b+b*b 根据上式可得:root(ab*ab) = a*a+2*a*b+b*b = (a+b)*(a+b);[公式一] 同理也可证得:root(ab*ab*ab) = (a+b)*(a+b)*(a+b)

简单数论

1.求gcd,算法为欧几里德(辗转相除法) 2.解一元二次方程,算法为扩展欧几里德 3.求素数,算法为埃氏筛法 4.快速进行幂运算,算法快速幂(反复平方) 5.解线性同余方程,求逆元(基于exgcd) 6.其它用来优化模运算的定理,欧拉定理(费马小定理),相应的函数欧拉函数 简单数论

简单数论之整除&质因数分解&唯一分解定理

[整除] 若a被b整除,即a是b的倍数,那么记作b|a("|"是整除符号),读作"a整除b"或"b能被a整除".a叫做b的约数(或因数),b叫做a的倍数. 简单数论之整除&质因数分解&唯一分解定理 原文地址:https://www.cnblogs.com/zjd-ac/p/10351608.html

codeforces 495B Modular Equations 简单数论~

链接:http://codeforces.com/problemset/problem/495/B 首先 a = b(mod x)  可以根据同余定理 b|a-b . 然后从1开始枚举到a-b. 还有一个定理,在sqrt(a-b)范围内 就可以枚举出所有的因子式,例如16,sqrt(16) = 4 , 1 * 16 = 16, 2*8 = 16, 4*4 = 16 再没有其它的式子了(卡在这里了...):: /*******************************************