求助莫反qwq
查看原帖
求助莫反qwq
230804
Durancer楼主2021/4/5 11:26

这是推出来的式子,cnt表示的是i出现的个数:

d=1max(a)k=1max(a)dμ(k)d(dkimax(a)i×cnti)2\sum_{d=1}^{max(a)}\sum_{k=1}^{\lfloor\frac{max(a)}{d}\rfloor}\frac{\mu(k)}{d}\left(\sum_{dk|i}^{max(a)}i\times cnt_i\right)^2

预处理貌似没有问题,找不出哪里出问题了qwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define int long long
using namespace std;
const int N=2e5+9;
const int M=1e6;
const int mod=998244353;
int n,m;
int a[N+10];
int sum[M+9];
int mu[M+9];
bool vis[M+9];
int prime[M+9];
int c[M+9];
int cnt;
int ans; 
int read()
{
	int f=1,x=0;
	char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=(x<<1)+(x<<3)+(s^'0');s=getchar();}
	return f*x;
}
int quick(int x,int p)
{
	int ret=1;
	while(p)
	{
		if(p&1) ret=ret*x%mod;
		x=x*x%mod;
		p>>=1;
	}
	return ret%mod;
}
void get_mu()
{
	mu[1]=1;
	for(int i=2;i<=m;i++)
	{
		if(!vis[i])
		{
			prime[++cnt]=i;
			mu[i]=-1;
		}
		for(int j=1;j<=cnt&&prime[j]<=m/i;j++)
		{
			vis[i*prime[j]]=true;
			if(i%prime[j]==0) break;
			mu[i*prime[j]]=-mu[i];
		}
	}
	//for(int i=1;i<=m;i++) cout<<mu[i]<<" ";
	
	for(int i=1;i<=m;i++)
		mu[i]+=mu[i-1];
	for(int i=1;i<=n;i++)
		c[a[i]]=(a[i]+c[a[i]])%mod;
	for(int j=1;j<=cnt;j++)
		for(int i=m/prime[j];i>=1;i--)
			c[i]=(c[i]+c[i*prime[j]])%mod;
	for(int i=1;i<=m;i++)
		c[i]=(c[i]*c[i])%mod;
	return;
}
signed main()
{
	n=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) m=max(m,a[i]);
	get_mu();
	for(int i=1;i<=m;i++)
	{
		int inv=quick(i,mod-2);
		cout<<inv<<endl;
		for(int j=1;j<=m/i;j++)
		{
			ans+=mu[j]*c[i*j]*inv; 
		}
	}
	for(int i=1;i<=n;i++) ans-=a[i];
	ans/=2;
	printf("%lld\n",ans);
	return 0;
}
2021/4/5 11:26
加载中...