并不对劲的bzoj3529:loj2193:p3312:[SDOI2014]数表

题目大意

定义函数(f(x)=sum_{k|x}k)
(t)((tleq2*10^4))组询问,每组给定(n,m,a)((n,mleq10^5,aleq10^9)),求:

[sum_{i=1}^{n}sum_{j=1}^{m}[f(gcd(i,j))leq a]f(gcd(i,j))space mod 2^{31} ]

题解

这个人(点这里)讲得很清楚(color{white}{ ext{shing太强了}})
除此之外,因为模数是2的整数次幂,所以需要模的时候可以直接按位与(2^{31}-1)

代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define maxn 100010 
#define lim (maxn-10)
#define LL long long
using namespace std;
int read()
{
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')f=-1,ch=getchar();
	while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return x*f;
}
void write(LL x)
{
	if(x==0){putchar('0'),putchar('
');return;}
	int f=0;char ch[20];
	if(x<0)putchar('-'),x=-x;
	while(x)ch[++f]=x%10+'0',x/=10;
	while(f)putchar(ch[f--]);
	putchar('
');
	return;
}
const LL mod=(1ll<<31)-1;
int t,no[maxn],p[maxn],cnt;
struct quest{int n,m,a,id;LL ans;}q[20010];
struct funct{int x;LL f;}fu[maxn];
LL mu[maxn],g[maxn];
int lt(int x){return x&(-x);}
void add(int x,LL k){for(;x<=lim;x+=lt(x))g[x]=(g[x]+k)&mod;}
LL ask(int x){LL k=0;for(;x;x-=lt(x))k=(k+g[x])&mod;return k;}
bool cmpa(quest x,quest y){return x.a<y.a;}
bool cmpf(funct x,funct y){return x.f<y.f;}
bool cmpid(quest x,quest y){return x.id<y.id;}
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	no[1]=mu[1]=1;
	rep(i,2,lim)
	{
		if(!no[i])p[++cnt]=i,mu[i]=-1;
		for(int j=1;j<=cnt&&i*p[j]<=lim;j++)
		{
			no[i*p[j]]=1;
			if(i%p[j]==0){mu[i*p[j]]=0;break;}
			mu[i*p[j]]=-mu[i];
		}
	}
	rep(i,1,lim)
	{
		fu[i].x=i;
		for(int j=i;j<=lim;j+=i)fu[j].f=(fu[j].f+i)&mod;
	}
	sort(fu+1,fu+lim+1,cmpf);
	t=read();
	rep(i,1,t)
	{
		q[i].n=read(),q[i].m=read(),q[i].a=read(),q[i].id=i;
		if(q[i].n>q[i].m)swap(q[i].n,q[i].m);
	}
	sort(q+1,q+t+1,cmpa);int now=0;
	rep(i,1,t)
	{
		while(now+1<=lim&&fu[now+1].f<=q[i].a)
		{
			now++;
			for(int j=fu[now].x;j<=lim;j+=fu[now].x)add(j,(mu[j/fu[now].x]*fu[now].f)&mod);
		}
		for(int l=1,r=0;l<=q[i].n;l=r+1)
		{
			r=min(q[i].n/(q[i].n/l),q[i].m/(q[i].m/l));
			q[i].ans=(q[i].ans+((((LL)(q[i].n/l)*(LL)(q[i].m/l))&mod)*((ask(r)-ask(l-1)+mod+1ll)&mod))&mod)&mod;
		}
	}
	sort(q+1,q+t+1,cmpid);
	rep(i,1,t)write(q[i].ans);
	return 0;
}

原文地址:https://www.cnblogs.com/xzyf/p/10451492.html