1. 程式人生 > >luogu P3312 [SDOI2014]數表

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); }