链接:https://www.nowcoder.com/acm/contest/215/D
来源:牛客网
题目描述
“我不知道你在说什么,因为我只是个pupil。”--绿魔法师
一个空的可重集合S。
n次操作,每次操作给出x,k,p,执行以下操作:
1、在S中加入x。
2、输出。
输入描述:
所有输入的数都是小于1e5+1的正整数。
输出描述:
输出对应的结果
输入
3 4 1 9 5 2 8 6 3 7
输出
4 2 1
如上,直接暴力右边两个求和即可
其中u(p)为p的莫比乌斯函数,复杂度O(nq²),其中q为任意数字的因子个数
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
vector<int> G[100005], F[100005];
int mod, sum[100005], pri[100005], mu[100005] = {0,1}, flag[100005] = {1,1};
long long Pow(long long a, int b)
{
long long ans = 1;
while(b)
{
if(b%2)
ans = ans*a%mod;
a = a*a%mod;
b /= 2;
}
return ans;
}
int main(void)
{
long long ans;
int now, n, i, j, x, k, temp, cnt, t;
scanf("%d", &n);
cnt = 0;
for(i=1;i<=100000;i++)
{
if(flag[i]==0)
{
pri[++cnt] = i;
mu[i] = -1;
}
for(j=1;j<=cnt&&i*pri[j]<=100005;j++)
{
flag[i*pri[j]] = 1;
if(i%pri[j]==0)
{
mu[i*pri[j]] = 0;
break;
}
mu[i*pri[j]] = -mu[i];
}
}
for(i=1;i<=100000;i++)
{
for(j=i;j<=100000;j+=i)
G[j].push_back(i);
if(mu[i]==0 || i==1)
continue;
for(j=i;j<=100000;j+=i)
F[j].push_back(i);
}
while(n--)
{
ans = 0;
scanf("%d%d%d", &x, &k, &mod);
for(i=G[x].size()-1;i>=0;i--)
{
now = G[x][i], sum[now]++;
cnt = sum[now], temp = x/now;
for(j=0;j<F[temp].size();j++)
{
t = F[temp][j];
cnt += sum[now*t]*mu[t];
}
ans = (ans+cnt*Pow(now, k))%mod;
}
printf("%lld\n", ans);
}
return 0;
}