hdu1695(容斥+莫比乌斯+欧拉函数)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qkoqhh/article/details/82054268

这题有2种做法,先说具有一般性的做法。。

思路就是容斥处理\sum_{i=1}^{n}[gcd(i,n)=1],枚举n的质因子,然后组合一下就可以了。。这个可以处理任何一个二维区间的gcd(x,y)==1的点对数。。考虑到素因子个数为loglogn个,复杂度是O(nlogn)

然后这题的特殊之处在于a=c=1,这样可以先求出整个区间的gcd=1的点数,然后再用欧拉函数把重复的点去调,因为此时去的点数就是比n小和n互质的所有点。。然后整个区间gcd=1的点可以这么求。。

\sum_{i=1}^{n} \sum_{j=1}^{m} [gcd(i,j)=1]=\sum_{i=1}^{n} \sum_{j=1}^{m} \sum_{d|i\&\&d|j}\mu(d)=\sum_{d}\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{m}{d} \right \rfloor}\mu(d)=\sum_{d}\mu(d)\left \lfloor \frac{n}{d} \right \rfloor\left \lfloor \frac{m}{d} \right \rfloor

然后这个可以分块求。。 将\left \lfloor \frac{n}{d} \right \rfloor相等的所有的d放在一起处理计数,对\left \lfloor \frac{n}{d} \right \rfloor的d的集合区间为[\left \lfloor \frac{n}{\left \lfloor \frac{n}{d} \right \rfloor+1} \right \rfloor+1,\left \lfloor \frac{n}{\left \lfloor \frac{n}{d} \right \rfloor} \right \rfloor],即每次算n/(n/d)事实上求出了n/d相同的区间的端点

然后分块姿势可以看代码,比较套路。。。复杂度O(sqrt(n))

容斥

/**
 *          ┏┓    ┏┓
 *          ┏┛┗━━━━━━━┛┗━━━┓
 *          ┃       ┃  
 *          ┃   ━    ┃
 *          ┃ >   < ┃
 *          ┃       ┃
 *          ┃... ⌒ ...  ┃
 *          ┃              ┃
 *          ┗━┓          ┏━┛
 *          ┃          ┃ Code is far away from bug with the animal protecting          
 *          ┃          ┃   神兽保佑,代码无bug
 *          ┃          ┃           
 *          ┃          ┃        
 *          ┃          ┃
 *          ┃          ┃           
 *          ┃          ┗━━━┓
 *          ┃              ┣┓
 *          ┃              ┏┛
 *          ┗┓┓┏━━━━━━━━┳┓┏┛
 *           ┃┫┫       ┃┫┫
 *           ┗┻┛       ┗┻┛
 */
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1LL<<(x))
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 100005
#define nm 200005
#define N 1000005
#define M(x,y) x=max(x,y)
const double pi=acos(-1);
const ll inf=1e9+7;
using namespace std;
ll read(){
    ll 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 f*x;
}
  


int m,n,_x,_t,cnt,tot,c[NM],ca;
ll ans;

void dfs(int i,int t){
    if(i==tot+1){cnt+=_x/t;return;}
    dfs(i+1,t);dfs(i+1,-t*c[i]);
}

int main(){
    int _=read();while(_--){
	n=read();n=read();m=read();m=read();_t=read();ans=0;
	if(n<m)swap(n,m);
	if(_t==0||n<_t){printf("Case %d: 0\n",++ca);continue;}
	n/=_t;m/=_t;
	inc(i,1,n){
	    int t=i;tot=0;_x=min(i,m);cnt=0;
	    for(int j=2;j*j<=t;j++)if(t%j==0){
		c[++tot]=j;while(t%j==0)t/=j;
	    }
	    if(t>1)c[++tot]=t;
	    dfs(1,1);
	    ans+=cnt;
	}
	printf("Case %d: %lld\n",++ca,ans);
    }
    return 0;
}

莫比乌斯+欧拉函数

/**
 *          ┏┓    ┏┓
 *          ┏┛┗━━━━━━━┛┗━━━┓
 *          ┃       ┃  
 *          ┃   ━    ┃
 *          ┃ >   < ┃
 *          ┃       ┃
 *          ┃... ⌒ ...  ┃
 *          ┃              ┃
 *          ┗━┓          ┏━┛
 *          ┃          ┃ Code is far away from bug with the animal protecting          
 *          ┃          ┃   神兽保佑,代码无bug
 *          ┃          ┃           
 *          ┃          ┃        
 *          ┃          ┃
 *          ┃          ┃           
 *          ┃          ┗━━━┓
 *          ┃              ┣┓
 *          ┃              ┏┛
 *          ┗┓┓┏━━━━━━━━┳┓┏┛
 *           ┃┫┫       ┃┫┫
 *           ┗┻┛       ┗┻┛
 */
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1LL<<(x))
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 500005
#define nm 1000005
#define N 1000005
#define M(x,y) x=max(x,y)
const double pi=acos(-1);
const int inf=20170817;
using namespace std;
ll read(){
    ll 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 f*x;
}
  
 

int prime[NM],tot,phi[NM],mu[NM],n,m,_t,ca;
ll ans,a[NM],b[NM];
bool v[NM];

void init(){
    a[1]=b[1]=mu[1]=phi[1]=1;n=1e5;
    inc(i,2,n){
    if(!v[i])prime[++tot]=i,phi[i]=i-1,mu[i]=-1;
    inc(j,1,tot){
        if(i*prime[j]>n)break;
        v[i*prime[j]]++;
        if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}
        phi[i*prime[j]]=phi[i]*(prime[j]-1);mu[i*prime[j]]=-mu[i];
    }
    a[i]=a[i-1]+phi[i];b[i]=b[i-1]+mu[i];
    }
}


int main(){
    init();
    int _=read();while(_--){
    n=read();n=read();m=read();m=read();_t=read();
    if(n>m)swap(n,m);
    if(_t==0||n<_t){printf("Case %d: 0\n",++ca);continue;}
    n/=_t;m/=_t;
    ans=-(a[n]-a[1]);
    for(int i=1,j=1;i<=n;i=j+1){
        j=min(n/(n/i),m/(m/i));
        ans+=(b[j]-b[i-1])*(n/i)*(m/i);
    }
    printf("Case %d: %lld\n",++ca,ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qkoqhh/article/details/82054268
今日推荐