It's a Mod, Mod, Mod, Mod World【类欧几里德模板】

题目链接
昨天比赛真的考了一个模板题。然而对于没有学过这个算法的我来说emmmm
这里考的是最基本的类欧几里得算法,用来算在这里插入图片描述
推导过程可以参考这篇博客,写得比较容易理解。
本题要求和的这个式子稍有不同在这里插入图片描述,变通一下,考虑模数计算的原理,可以知道a mod b = a - floor(a/b)*b,代入上面那个式子可以得到要求的结果ans = p × n(n+1)/2 - q × Σ[pi / q]
直接套类欧几里德算法公式,结束
AC:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <string>
#define ll long long
using namespace std;
ll p,q,n0,t;
ll likegcd(ll a,ll b,ll c,ll n)
{
    if(a==0)return 0;
    if(a>=c||b>=c)
    {
        return ((n+1)*n/2)*(a/c)+(n+1)*(b/c)+likegcd(a%c,b%c,c,n);
    }
    else
    {    ll m = (a*n+b)/c;
         return n*m - likegcd(c,c-b-1,a,m-1);
    }
}
ll getnum()
{
    ll ans=0;
    bool f=1;
    char c=getchar();
    while(!isdigit(c))
    {
        if(c=='-')f=0;
        c=getchar();
    }
    while(isdigit(c))
    {
        ans=ans*10+c-'0';
        c=getchar();
    }
    return f ? ans : -ans;
}
int main()
{
    t=getnum();
    while(t--)
    {
        p=getnum(),q=getnum(),n0=getnum();
        printf("%lld\n",p*(n0*(n0+1)/2)-q*likegcd(p,0,q,n0));//再忘乘q就去抄小学数学课本
    }
    return 0;
}

你可能感兴趣的:(题解)