zoukankan      html  css  js  c++  java
  • 【BZOJ3994】[SDOI2015]约数个数和 莫比乌斯反演

    【BZOJ3994】[SDOI2015]约数个数和

    Description

     设d(x)为x的约数个数,给定N、M,求  

    Input

    输入文件包含多组测试数据。

    第一行,一个整数T,表示测试数据的组数。
    接下来的T行,每行两个整数N、M。

    Output

     T行,每行一个整数,表示你所求的答案。

    Sample Input

    2
    7 4
    5 6

    Sample Output

    110
    121

    HINT

     1<=N, M<=50000

    1<=T<=50000

    题解:依旧是这个结论

    但由于这次是多组询问,我们先O(nsqrt(n))预处理,然后就能O(sqrt(n))回答询问了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    const int m=50000;
    int sm[m+10],mu[m+10],pri[m+10];
    bool np[m+10];
    int T,num;
    ll x,y;
    ll  f[m+10];
    int main()
    {
    	ll i,j,last,ans,x,y;
    	sm[1]=mu[1]=1;
    	for(i=2;i<=m;i++)
    	{
    		if(!np[i])	pri[++num]=i,mu[i]=-1;
    		sm[i]=sm[i-1]+mu[i];
    		for(j=1;j<=num&&i*pri[j]<=m;j++)
    		{
    			np[i*pri[j]]=1;
    			if(i%pri[j]==0)
    			{
    				mu[i*pri[j]]=0;
    				break;
    			}
    			mu[i*pri[j]]=-mu[i];
    		}
    	}
    	for(i=1;i<=m;i++)	for(j=1;j<=i;j=last+1)	last=i/(i/j),f[i]+=(last-j+1)*(i/j);
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%lld%lld",&x,&y),ans=0;
    		if(x<y)	swap(x,y);
    		for(i=1;i<=y;i=last+1)
    		{
    			last=min(x/(x/i),y/(y/i));
    			ans+=(sm[last]-sm[i-1])*f[x/i]*f[y/i];
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
  • 相关阅读:
    自定义动画animate()
    【Java】正则表达式
    【Java】连接数据库SQLServer
    【Java】导入导出TXT文件
    【数据库】SELECT语句
    数据结构与算法系列之目录
    【Java】员工统计
    【Java】生产者消费者模式
    【Java】购物超市
    【Java】导入导出Excel表格
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6999507.html
Copyright © 2011-2022 走看看