HDU 2841 Visible Trees (容斥原理好题)

Visible Trees 
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit  Status

Description

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.

Input

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)

Output

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

Sample Input

2
1 1
2 3

Sample Output

1
5


这是一道精妙的容斥原理,我看了两个小时,看得懵懵懂懂,前神指点一下子懂了容斥原理的精妙。

题意:给定一个 m * n 的方格, 左下角的点为(1,1),右上角的点(n,m) ,然后每个方格都是一棵树,然后一个
人站在(0,0)点,往森林里看,当两棵树在一条线上的时候 ,它只能看到最前面的那个点, 后面的树就不计
了,计算能够看到多少颗树。
尴尬的是我还理解错题意好几遍 【汗】
对于(x,y)之间如果有公约数为D(D!=1),x1/y1=x/D/(y/D)所以(x,y)就被挡住了,如果(x,y)
之间有公约数,那么(X,y)就被挡住了,N*M-被挡住的(x,y)就是答案。1-m和1-n的公约数用Gcd判断肯
定会超时,所以就考虑1到【1-m】之间有多少个数不互质,2到【1-m】之间有多少个数不互质……n到【1-m】
之间有多少个数不互质。n*M减去这些数就是答案。怎么转化成容斥原理的代码呢,把他们转化为有几个素因子
(素因子!!我看了长时间代码才注意到这个素字。)奇数加偶数减正是容斥原理的核心,举个小栗子12到【1-16】之间有多少个数不互质呢?12的素因子有2,3没了,4不是素的是荤的-_-. 16/2-16/2/3+16/3就是12行16个数中
有几个被挡住的16/2是代表有2 4 6 8……16共8个和12有公约数,16/3是3,6……15共16/3即5个和12有公约数3
必须减去6.,12这些算两次的,所以明白了原理,下面上代码,希望有大家有帮助,不懂请留言:


挡住我的时间长,收获也大,
enjoy coding, enjoy sharing! 
#include 
#include 
#include 
using namespace std;
const int MAXN = 1e5+5;
typedef __int64 LL;




int prime[MAXN][20];  ///每个数有几个素因子 一般不超过20 打表
int cnt[MAXN];///i有几个素因子
void Init()
{
    memset(cnt, 0,sizeof(cnt));
   for(int i=2;i>T;
    while(T--)
    {
        cin>>m>>n;


        LL ret = m;


      for(int i=2;i<=n;i++)
        ret+=m-RongChi(i,m,0);
        printf("%I64d\n",ret);
    }
    return 0;
}

功未成,身未退。

你可能感兴趣的:(ACM-组合数学)