[BZOJ 2301] [HAOI2011] Problem b
2015-06-23 20:10
246 查看
2301: [HAOI2011]Problem b
Time Limit: 50 SecMemory Limit: 256 MBDescription
对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。Input
第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、kOutput
共n行,每行一个整数表示满足要求的数对(x,y)的个数Sample Input
22 5 1 5 1
1 5 1 5 2
Sample Output
143
HINT
100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000【题解】莫比乌斯反演+前缀和处理即可。
分四段,然后容斥即可。
#include <cstdio> #define min(x,y) x<y?x:y using namespace std; int mu[50010]; bool chk[50010]; int prime[50010],tot=0; long long getsum(int x,int y) { long long re=0; int f=min(x,y),la; for (int i=1;i<=f;i=la+1) { la=min(x/(x/i),y/(y/i)); re+=(long long)(x/i)*(y/i)*(mu[la]-mu[i-1]); } return re; } int main() { //scanf("%d",&n); mu[1]=1; for (int i=2;i<=50000;++i) { if (!chk[i]) { prime[++tot]=i; mu[i]=-1; } for (int j=1;j<=tot&&i*prime[j]<=50000;++j) { chk[i*prime[j]]=1; if(i%prime[j]==0) { mu[i*prime[j]]=0; break; } mu[i*prime[j]]=-mu[i]; } } mu[0]=0; for (int i=2;i<=50000;++i) mu[i]+=mu[i-1]; int t; scanf("%d",&t); while(t--) { int a,b,c,d,k; scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); printf("%lld\n",getsum(b/k,d/k)-getsum((a-1)/k,d/k)-getsum(b/k,(c-1)/k)+getsum((a-1)/k,(c-1)/k)); } return 0; }
View Code
相关文章推荐
- Java知多少(101)图像缓冲技术
- 微信JSSDK使用指南
- UIScrollView
- linux下DMA驱动测试代码
- html form表单提交数据并后台获取
- 面试常见算法-排序查找算法
- urban terror 不能下载地图
- AngularJs ng-model在input中无效,js无法调用
- Android入门之GridView(九宫图)
- android-RecyclerView
- PCB入门时候的错误归纳(第一次PCB走线)
- display和visibility隐藏元素
- Django permission
- Android深入浅出之Zygote
- 避免放大器电路设计中的常见问题
- dwm窗口水平分割
- html背景音乐
- Python学习 之 文件
- make参数详解
- 建立使用Cas进行单点登录的应用