hdu 2841 Visible Trees【容斥原理】

简介: Visible Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1602    Accepted Submis...

Visible Trees

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1602    Accepted Submission(s): 661


Problem 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)的矩阵,每个点上有一颗树,你站在(0,0)点看矩阵,前面的树会挡着后面的树,问你此时一共可以看到多少树!
结题思路:由于是站在(0,0),因此此时被挡的那棵树(X,Y)和挡它的那棵树(x,y)有一些关系,此时和(0,0)三点共线,因此X / x == Y / y;
因此(X,Y)必有公约数,因此点任意一点(A,B)只要A,B有约数,则一定看不到,反之,A,B互质则一定可以看到,因此问题转化为求图中的互质点对;
说到求互质,第一想起来的就是gcd,但是gcd求起来必然耗时,因此可以用容斥原理,前面的博客已经介绍了利用容斥原理求M和1-N中有多少互质,那么现在是求1-M中的所有数与1-N中有多少互质,因此循环1—N即可!
#include<cstdio>
#define LL long long
int p[10],top;
void getp(int v){
    top=0;
    for(int i=2;i*i<=v;i++){
        if(v%i==0){
            p[top++]=i;
            while(v%i==0) v/=i;
        }
    }
    if(v>1)p[top++]=v;
}
LL nop(int n,int t){
    int i;
    LL num=0;
    for(i=t;i<top;i++)
        num+=n/p[i]-nop(n/p[i],i+1);
    return num;
}
int main(){
    int t,m,n,i;
    LL sum;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&m,&n);
        sum=n;
        for(i=2;i<=m;i++){
            getp(i);
            sum+=(n-nop(n,0));
        }
        printf("%lld\n",sum);
    }
}
 
  
说实话代码超短,但是还是WA了3次,原因很简单,nop忘了写返回值,而且getp函数中,把while误写成if,真不知道自己写代码的时候想的啥,过了一天静下心来才改对
翻别人的博客,发现直接进行预处理素数表,可以省一部分时间,但是耗内存,下面贴代码
#include<cstdio>
#define LL long long
int prime[100005][20];
int cnt[100005]={0};
void Init(){
    for(int i=2;i<=100000;i++){
        if(cnt[i]) continue;
        prime[i][0]=i;
        cnt[i]=1;
        for(int j=2;j*i<=100000;j++)
            prime[i*j][cnt[i*j]++]=i;
    }
}
LL dfs(int m,int n,int idx){
    LL ret=0;
    for(int i=idx;i<cnt[m];i++)
        ret+=n/prime[m][i]-dfs(m,n/prime[m][i],i+1);
    return ret;
}
int main(){
    Init();
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        LL ans=n;
        for(int i=2;i<=m;i++)
            ans+=(n-dfs(i,n,0));
        printf("%I64d\n",ans);
    }
    return 0;
}
 
 
目录
相关文章
|
开发框架 .NET
poj 3468 A Simple Problem with Integers线段树区间修改
题目意思很简单,有N个数,Q个操作, Q l r 表示查询从l到r 的和,C l r v 表示将从l到r 的值加上v,明显的线段树,不知道线段树的人肯定暴力,肯定超时,哈哈!!
30 0
HDU 1506 Largest Rectangle in a Histogram(单调栈)
HDU 1506 Largest Rectangle in a Histogram(单调栈)
HDU-1097,A hard puzzle(快速幂)
HDU-1097,A hard puzzle(快速幂)
|
算法 Go
HDU-1548,A strange lift(Dijkstra)
HDU-1548,A strange lift(Dijkstra)
|
C语言
HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)
HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)
97 0
HDOJ/HDU 1372 Knight Moves(经典BFS)
HDOJ/HDU 1372 Knight Moves(经典BFS)
132 0
HDOJ(HDU) 2401 Baskets of Gold Coins(数列、)
HDOJ(HDU) 2401 Baskets of Gold Coins(数列、)
79 0
|
人工智能 Java