ガーナーのアルゴリズム
(math/garner.hpp)
Depends on
Required by
Verified with
Code
#pragma once
#include<vector>
#include"mod_pow.hpp"
/**
*
* @brief ガーナーのアルゴリズム
*
*/
long long garner(const std::vector<long long>&a,const std::vector<long long>&mods){
const int sz=a.size();
long long coeffs[sz+1]={1,1,1,1};
long long constants[sz+1]={};
for(int i=0;i<sz;i++){
long long v=(mods[i]+a[i]-constants[i])%mods[i]*mod_pow(coeffs[i],mods[i]-2,mods[i])%mods[i];
for(int j=i+1;j<sz+1;j++) {
constants[j]=(constants[j]+coeffs[j]*v)%mods[j];
coeffs[j]=(coeffs[j]*mods[i])%mods[j];
}
}
return constants[sz];
}
#line 2 "math/garner.hpp"
#include<vector>
#line 1 "math/mod_pow.hpp"
/**
* @brief (x^y)%mod
*/
long long mod_pow(long long x,long long y,long long mod){
long long ret=1;
while(y>0) {
if(y&1)(ret*=x)%=mod;
(x*=x)%=mod;
y>>=1;
}
return ret;
}
#line 4 "math/garner.hpp"
/**
*
* @brief ガーナーのアルゴリズム
*
*/
long long garner(const std::vector<long long>&a,const std::vector<long long>&mods){
const int sz=a.size();
long long coeffs[sz+1]={1,1,1,1};
long long constants[sz+1]={};
for(int i=0;i<sz;i++){
long long v=(mods[i]+a[i]-constants[i])%mods[i]*mod_pow(coeffs[i],mods[i]-2,mods[i])%mods[i];
for(int j=i+1;j<sz+1;j++) {
constants[j]=(constants[j]+coeffs[j]*v)%mods[j];
coeffs[j]=(coeffs[j]*mods[i])%mods[j];
}
}
return constants[sz];
}
Back to top page