Wannafly挑战赛27: D. 绿魔法师(莫比乌斯函数)

版权声明:本文为博主原创文章,你们可以随便转载 https://blog.csdn.net/Jaihk662/article/details/83422151

链接: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;
}

猜你喜欢

转载自blog.csdn.net/Jaihk662/article/details/83422151
今日推荐