HDU2841 Visible Trees(容斥原理)

题目。。大概就是有个m*n个点的矩形从(1,1)到(m,n),问从(0,0)出发直线看过去最多能看到几个点。

如果(0,0)->(x,y)和(0,0)->(x‘,y‘)两个向量平行,那后面的那个点就看不到了。

因此给出一个点(x,y),判断它能否被看到,就是是否能找到一个大于1的k,使k|x且k|y。

这样,问题就能转变为有几个点的x、y找不到公约数,即有几对x、y,满足x和y互质。

可以通过枚举x,看有几个y与其互质累加。这样问题就又变成,区间有几个数与某个数互质,经典的容斥问题HDU4135

时间复杂度方面,1 ≤ m, n ≤ 100000,前7个素数乘积就超过100000了,即一个数最多有6个质因数,大概估个非常松的上界$O((\sqrt m+2^6)n)$,应该是妥妥的。

#include<cstdio>
#include<cstring>
using namespace std;
int prime[7],pn;
int getCnt(int n,int m){
    pn=0;
    for(int i=2; i*i<=m; ++i){
        if(m%i) continue;
        while(m%i==0) m/=i;
        prime[pn++]=i;
    }
    if(m!=1) prime[pn++]=m;
    int res=0;
    for(int i=1; i<(1<<pn); ++i){
        int tmp=1,cnt=0;
        for(int j=0; j<pn; ++j){
            if(((i>>j)&1)==0) continue;
            tmp*=prime[j];
            ++cnt;
        }
        if(cnt&1) res+=n/tmp;
        else res-=n/tmp;
    }
    return n-res;
}
int main(){
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        long long res=0;
        for(int i=1; i<=n; ++i){
            res+=getCnt(m,i);
        }
        printf("%lld\n",res);
    }
    return 0;
}
时间: 2024-10-22 15:21:41

HDU2841 Visible Trees(容斥原理)的相关文章

HDU2841 Visible Trees (容斥原理)

主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2841 题意: 一个人在(0,0)点,然后前面有一个m*n的格子 ,每一个格子的节点上有一棵树.问这个人站在原地能看到多少棵树 假设两棵树在一条直线上那么仅仅能看到最前面的一棵树. 分析: 假设一个数的坐标为(a,b).那么坐标为(a*k,b*k)的都不能看见.假设a,b有公因子c那么我们肯定仅仅能看到(a/c,b/c). 因此我们得出结论,能看到的树的横纵坐标一定互质. 那么我们就能够把问题转化为,

hdu 2841 Visible Trees 容斥原理

Visible Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) 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 ma

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 Submission(s): 661 Problem Description There are many trees forming a m * n grid, the grid starts from (1,1). Farm

hdu 4135 Co-prime +hdu 2841 Visible Trees(容斥原理)

Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2263    Accepted Submission(s): 847 Problem Description Given a number N, you are asked to count the number of integers between A and B

Visible Trees(hdu2841)

Visible Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2462    Accepted Submission(s): 1032 Problem Description There are many trees forming a m * n grid, the grid starts from (1,1). Farm

[思维+容斥原理] hdu 2841 Visible Trees

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2841 Visible Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1337    Accepted Submission(s): 552 Problem Description There are many trees f

hdu2848 Visible Trees (容斥定理)

题意: 给n*m个点(1 ≤ m, n ≤ 1e5),左下角的点为(1,1),右上角的点(n,m),一个人站在(0,0)看这些点.在一条直线上,只能看到最前面的一个点,后面的被档住看不到,求这个人能看到多少个点. 知识点: 容斥原理:(容许) 先不考虑重叠的情况,把包含于某条件中的所有对象的数目先计算出来,(排斥)然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复. 公式:          奇加偶减 一般求互质个数若用欧拉函数不好解决,则从反面考虑,用容斥. 模板: void

HDU 2841 Visible Trees

Visible Trees Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 284164-bit integer IO format: %I64d      Java class name: Main There are many trees forming a m * n grid, the grid starts from (1,1). Farmer Sherl

HDU 2841 Visible Trees(数论)

题目大意:给你一个m*n的方格,方格从(1,1)开始.每个点上有一棵树,然后让你从(0,0)点向下看,问你能看见几颗树. 解题思路:如果你的视线被后面的树和挡住的话以后在这条线上的树你是都看不见的啊.挡住的话就是这个小的方格内对角线的连线过顶点,如图: 建设A为(0,0)如果B能遮挡住C,那么B与C组成的矩形中nx, mx是不互质的. 所以x从1开始枚举n如果m中某一项与x互质那么就会有一个格子显示出来,所以这里需要找的是1-n中与枚举的x互质的个数.这里的话我们可以用到分解质因数,然后用状态压