类欧几里得

P5170 【模板】类欧几里得算法

 

 

 

类欧几里得_第1张图片

 

 

 类欧几里得_第2张图片

 

 

 

///类欧几里得的模板题  p5170
//求这三个式子;
//第一个跟后两个没关联
//后两个跟其余两个都有关联;


#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll inv2=499122177;
const ll inv6=166374059;
const ll mod=998244353;
int t;
ll n,a,b,c;
struct query
{
    ll f;
    ll g;
    ll h;
};
query solve(ll a,ll b,ll c,ll n)
{
    query ans,prec;
    if(a==0){
        ans.f=(b/c)*(n+1)%mod;
        ans.h=(b/c)*n%mod*(n+1)%mod*inv2%mod;
        ans.g=(b/c)*(b/c)%mod*(n+1)%mod;
    }
    else if(a>=c||b>=c){
        prec=solve(a%c,b%c,c,n);
        ans.f=(prec.f+n*(n+1)%mod*inv2%mod*(a/c)%mod+(n+1)*(b/c)%mod)%mod;
        ans.h=((a/c)*n%mod*(n+1)%mod*(2*n+1)%mod*inv6%mod+
               (b/c)*n%mod*(n+1)%mod*inv2%mod+prec.h)%mod;
        ans.g=(prec.g+(a/c)*(a/c)%mod*n%mod*(n+1)%mod*(2*n+1)%mod*inv6%mod+
               (n+1)*(b/c)%mod*(b/c)%mod+2*(a/c)%mod*prec.h%mod+
               2*(b/c)%mod*prec.f%mod+2*(a/c)%mod*(b/c)%mod*n%mod*(n+1)%mod*inv2%mod)%mod;
    }
    else{
        ll m=(a*n+b)/c;
        prec=solve(c,c-b-1,a,m-1);
        ans.f=(n*(m%mod)%mod-prec.f)%mod;
        ans.h=(n*(n+1)%mod*(m%mod)%mod-prec.f-prec.g)%mod*inv2%mod;
        ans.g =(n*(m%mod)%mod*((m+1)%mod)%mod-2*prec.h-2*prec.f-ans.f)%mod;
    }
    return ans;
}
void init()
{
        scanf("%d",&t);
    while(t--){
        scanf("%lld%lld%lld%lld",&n,&a,&b,&c);
        query ans=solve(a,b,c,n);
        printf("%lld %lld %lld\n", (ans.f + mod) % mod, (ans.g + mod) % mod, (ans.h + mod) % mod);
    }
}
int main()
{
    init();
    return 0;
}

  

你可能感兴趣的:(类欧几里得)