Visible Trees HDU

来源:互联网 发布:自动化交易编程设计 编辑:程序博客网 时间:2024/06/05 03:19


Visible Trees HDU - 2841  


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.

The first line contains one integer t, represents the number of test cases. Then there are multiple test cases. For each test case there is one line containing two integers m and n(1 ≤ m, n ≤ 100000)

For each test case output one line represents the number of trees Farmer Sherlock can see.

Input

2
1 1
2 3

Output

1
5



题意: 给定一个m*n 的棋盘,起点从(1,1)开始,你站在 (0,0) 看,问能看见多少个格子里的树,同一条直线上的格子里的树只能看见一个。

思路: 开始想半天没想到用容斥怎么做,然后发现对于每个不能被看见的格子,满足gcd(a,b)!=1 ,即判断该格子所在的坐标(a,b)  看是否满足 gcd ( a,b )==1  ,如果是的就加一。

那么问题就变成了从 1~H 在1~W区间里的互质的数的个数, 数据 H,W不是很大,可以固定一个,遍历一边求解,那么这个题就跟上个题是一样的了。



#pragma comment(linker, "/STACK:1024000000,1024000000")//#include <bits/stdc++.h>#include<string>#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<queue>#include<stack>#include<vector>#include<algorithm>#define maxn 100100#define INF 0x3f3f3f3f#define eps 1e-8#define MOD 1000000007#define ll long longusing namespace std;ll Q[maxn],fac[maxn];ll num;void Divide(ll n){    num=0;    for(ll i=2;i*i<=n;i++)    {        if(n%i==0)        {            while(n%i==0)                n/=i;            fac[num++]=i;        }    }    if(n!=1) fac[num++]=n;}ll solve(ll n){    ll k,t,ans;    t=ans=0;    Q[t++]=-1;    for(ll i=0;i<num;i++)    {        k=t;        for(ll j=0;j<k;j++)            Q[t++]=-1*Q[j]*fac[i];    }    for(ll i=1;i<t;i++)        ans+=n/Q[i];    return ans;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        ll H,W,ans;        scanf("%lld%lld",&H,&W);        if(H<W) swap(H,W);        ans=H;        for(ll i=2;i<=W;i++)        {            Divide(i);            ans+= (H-solve(H));        }        printf("%lld\n",ans);    }    return 0;}



原创粉丝点击