luogu P3312 [SDOI2014]数表

背景:

以下图片均来自我的 P D F PDF 文件,谢绝转载。

题目传送门:

https://www.luogu.org/problemnew/show/P3312

题意:

在这里插入图片描述

思路:

在这里插入图片描述
在这里插入图片描述

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define lowbit(x) ((x)&(-(x)))
#define mod 2147483648ll
#define ma 100000
using namespace std;
	struct node1{int x,y,z,id;} a[100010];
	struct node2{int x,id;} d[100010];
	int prime[100010];
	LL mu[100010],sum_mu[100010],c[100010],ans[100010];
	bool bz[100010];
bool cmp1(node1 x,node1 y)
{
	return x.z<y.z;
}
bool cmp2(node2 x,node2 y)
{
	return x.x<y.x;
}
void add(int x,LL y)
{
	while(x<=ma)
	{
		c[x]+=y;
		x+=lowbit(x);
	}
}
LL getsum(int x)
{
	LL sum=0;
	while(x)
	{
		sum+=c[x];
		x-=lowbit(x);
	}
	return sum;
}
void init()
{
	int t=0;
	mu[1]=sum_mu[1]=1;
	bz[0]=bz[1]=true;
	for(int i=2;i<=ma;i++)
	{
		if(!bz[i]) prime[++t]=i,mu[i]=-1;
		for(int j=1;j<=t&&(LL)i*prime[j]<=ma;j++)
		{
			bz[i*prime[j]]=true;
			if(!(i%prime[j]))
			{
				mu[i*prime[j]]=0;
				break;
			}
			mu[i*prime[j]]=-mu[i];
		}
		sum_mu[i]=sum_mu[i-1]+mu[i];
	}
	
	for(int i=1;i<=ma;i++)
	{
		d[i].id=i;
		for(int j=i;j<=ma;j+=i)
			d[j].x+=i;
	}
	sort(d+1,d+ma+1,cmp2);
}
LL calc(int n,int m)
{
	int l=1,r;
	LL tot=0;
	while(l<=min(n,m))
	{
		r=min(n/(n/l),m/(m/l));
		tot+=(n/l)*(m/l)*(getsum(r)-getsum(l-1));
		l=r+1;
	}
	return tot;
}
int main()
{
	int T;
	init();
	scanf("%d",&T);
	for(int i=1;i<=T;i++)
	{
		scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].z);
		a[i].id=i;
	}
	sort(a+1,a+T+1,cmp1);
	int tmp=0;
	for(int i=1;i<=T;i++)
	{
		while(tmp<ma&&d[tmp+1].x<=a[i].z)
		{
			tmp++;
			for(int j=1;j*d[tmp].id<=ma;j++) add(j*d[tmp].id,mu[j]*d[tmp].x);
		}
		ans[a[i].id]=calc(a[i].x,a[i].y);
	}
	for(int i=1;i<=T;i++)
		printf("%lld\n",ans[i]%mod);
}

猜你喜欢

转载自blog.csdn.net/zsyz_ZZY/article/details/84987382