hdu2841 Visible Tree

来源:互联网 发布:vs可以写python吗 编辑:程序博客网 时间:2024/06/04 19:45

题目的意思是从(0,0)这个点去看一个矩阵,这样的话每条线就只能看到第一个了,如果把一条直线上的坐标表示为(ai,bi)的话,他们拥有的特点就是ai/bi = k ,此题也就是找k的不同个数。由于每一个k都唯一对应一组互质的(a,b),那么此题转换成了求(100000,100000)内的互质对的对数。

#include<stdio.h>
#include<string.h>

// count[n]记录n有多少个质因子,num[i][j]表示数i中的第j个因子是多少
__int64 prim[100001],count[100001],num[100001][20];
__int64 not_prim(int m,int n,int k) // 在1——n中有多少个数与m不是互质的
{
int i,j;
__int64 ans=0;
if(m==1) return 0;
for(i=k;i<count[m];i++) // 用递归实现容斥原理。n/num[m][i]表示在1——n中有n/num[m][i]个数,被m的第i
ans+=n/num[m][i]-not_prim(m,n/num[m][i],i+1); // 个质因数整除
return ans;
}
int main()
{
int t,n,m,i,j;
memset(prim,0,sizeof(prim));
memset(count,0,sizeof(count));
for(i=2;i<=100000;i++) // 将1——100000中的所有数进行质因数分解
if(prim[i]==0)
{
num[i][0]=i;
count[i]++;
for(j=i*2;j<=100000;j+=i)
{
num[j][count[j]]=i;
count[j]++;
prim[j]=1;
}
}
scanf("%d",&t);
while(t--){
scanf("%d%d",&m,&n);
if(m>n)
{
int temp=n;
n=m;
m=temp;
}
__int64 ans=n;
for(i=2;i<=m;i++) //容斥原理:在1——n中与i互质的个数等于n减去所有能被i的质因数整除的个数
ans+=n-not_prim(i,n,0);
printf("%I64d\n",ans);
}
return 0;
}

原创粉丝点击