luogu P3312 [SDOI2014]數表
阿新 • • 發佈:2018-12-15
背景:
以下圖片均來自我的
檔案,謝絕轉載。
題目傳送門:
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);
}