您的位置:首页 > 其它

BZOJ2301: [HAOI2011]Problem b

2015-12-01 20:34 253 查看
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2301

莫比乌斯函数,记录前缀和分块,然后容斥。

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define maxn 50050
using namespace std;
int a,b,c,d,k,n,tot;
int sum[maxn],pri[maxn],mo[maxn],vis[maxn];
int read(){
int x=0,f=1; char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
void getmo(){
mo[1]=1;
rep(i,2,50000){
if (!vis[i]) vis[i]=1,pri[++tot]=i,mo[i]=-1;
rep(j,1,tot){
if (i*pri[j]>50000) break;
vis[i*pri[j]]=1;
if (i%pri[j]==0) {mo[i*pri[j]]=0; break;}
else mo[i*pri[j]]=-mo[i];
}
}
rep(i,1,50000) sum[i]=sum[i-1]+mo[i];
}
int go(int n,int m){
int i=1,ans=0;
while (i<=min(n,m)){
int pos=min(n/(n/i),m/(m/i));
ans+=(sum[pos]-sum[i-1])*(n/i)*(m/i);
i=pos+1;
}
return ans;
}
int main(){
getmo();
n=read();
rep(i,1,n){
a=read(); b=read(); c=read(); d=read(); k=read(); a--; c--;
a/=k; b/=k; c/=k; d/=k;
printf("%d\n",go(b,d)+go(a,c)-go(a,d)-go(b,c));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: