题目链接Wannafly挑战赛27 D-绿魔法师
预处理出每个数的因子,求出对于每个 d (因子),
gcd 为 d 的数的个数。然后直接对于每个 d 直接快速幂
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
struct ios {
inline char read(){
static const int IN_LEN=1<<18|1;
static char buf[IN_LEN],*s,*t;
return (s==t)&&(t=(s=buf)+fread(buf,1,IN_LEN,stdin)),s==t?-1:*s++;
}
template <typename _Tp> inline ios & operator >> (_Tp&x){
static char c11,boo;
for(c11=read(),boo=0;!isdigit(c11);c11=read()){
if(c11==-1)return *this;
boo|=c11=='-';
}
for(x=0;isdigit(c11);c11=read())x=x*10+(c11^'0');
boo&&(x=-x);
return *this;
}
} io;
ll ksm(ll a,ll b,ll p){
ll ret=1;
while(b){
if(b&1){
ret=ret*a%p;
}
b>>=1;
a=a*a%p;
}
return ret;
}
ll n,x,k,p;
vector<int>a[maxn];
int pre[maxn],ret[maxn];
int cnt[maxn];
int top=-1;
int main(){
for(int i=1;i<=maxn-10;i++){
for(int j=1;i*j<=maxn-10;j++){
a[i*j].push_back(i);
}
}
io>>n;
ll ans=0;
for(int i=1;i<=n;i++){
io>>x>>k>>p;
ans=0;
for(auto it=a[x].begin();it!=a[x].end();++it) cnt[*it]++;
for(auto it=a[x].rbegin();it!=a[x].rend();++it){
if(!cnt[*it]) continue;
ans=(ans+cnt[*it]*ksm(*it,k,p))%p;
for(auto t=a[*it].begin();t!=a[*it].end();++t){
pre[++top]=*t;ret[top]=cnt[*it];
cnt[*t]-=cnt[*it];
}
}
while(~top){
cnt[pre[top]]+=ret[top];
top--;
}
printf("%lld\n",ans);
}
return 0;
}