Visible Trees
There are many trees forming a m * n grid, the grid starts from (1,1). Farmer Sherlock is standing at (0,0) point. He wonders how many trees he can see.
If two trees and Sherlock are in one line, Farmer Sherlock can only see the tree nearest to him.
If two trees and Sherlock are in one line, Farmer Sherlock can only see the tree nearest to him.
Output
Sample Input
2 1 1 2 3
Sample Output
题目大意:在一个n*m的方格中一个人站在(0,0),每个方格都有树,求他能看到多少颗树,在同一条直线上只能看到离他最近的一棵。
1 5
题目分析:第一列的所有树都能看到,因为没有任何阻挡,从第二列开始,因为列数是确定的,所有与列互质的数,即横坐标,可以看到。然后依次类推,直到最后一列。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int mx=1e5+5;
vector<int>x[mx];
bool visited[mx];
void getPrimeFactor()///预处理1~mx内数的素因子,并存储起来,很巧妙
{
memset(visited,true,sizeof(visited));
for(int i=2;i<mx;i++)
if(visited[i])
{
for(int j=i;j<mx;j+=i)
{
visited[j]=false;
x[j].push_back(i);
}
}
}
int solve(int a,int p)///求区间[1,a]中与p互质的个数
{
int sum=0;
for(int i=1;i<(1<<x[p].size());i++)
{
int cnt=0,val=1;
for(int j=0;j<x[p].size();j++)
if(i&(1<<j))
{
cnt++;
val*=x[p][j];
}
if(cnt&1)
sum+=a/val;
else
sum-=a/val;
}
return a-sum;
}
int main()
{
getPrimeFactor();
int t;
int a,b;
cin>>t;
while(t--)
{
scanf("%d%d",&a,&b);
long long ans=a;///第一列所有的元素的都满足
for(int i=2;i<=b;i++)///从第二列到到第b列满足与i互质的满足
{
ans+=solve(a,i);
}
cout<<ans<<endl;
}
return 0;
}