HDU 2841 Visible Trees(容斥)题解

题意:有一块(1,1)到(m,n)的地,从(0,0)看能看到几块(如果两块地到看的地方三点一线,后面的地都看不到)。

思路:一开始是想不到容斥...后来发现被遮住的地都有一个特点,若(a,b)有gcd(a,b)!= 1,那么就会被遮住。因为斜率k一样,后面的点会被遮住,如果有gcd,那么除一下就会变成gcd = 1的那个点的斜率了。所以问题转化为求gcd不为1有几个点,固定一个点,然后容斥。

#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 1000 + 10;
const int seed = 131;
const int MOD = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
int prime[maxn], p[maxn], pn;
int a[maxn], an;
void get(){
    memset(p, 0, sizeof(p));
    pn = 0;
    for(ll i = 2; i < maxn; i++){
        if(!p[i]){
            prime[pn++] = i;
            for(ll j = i * i; j < maxn; j += i)
                p[j] = 1;
        }
    }
}
int main(){
    int n, m;
    int T;
    get();
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &m);
        ll ans = m;
        for(int i = 2; i <= n; i++){
            ll cnt = 0;
            //质因数分解
            an = 0;
            int x = i;
            for(int j = 0; prime[j] * prime[j] <= x && j < pn; j++){
                if(x % prime[j] == 0){
                    a[an++] = prime[j];
                    while(x % prime[j] == 0){
                        x /= prime[j];
                    }
                }
            }
            if(x > 1) a[an++] = x;
            //求gcd不为1
            for(int j = 1; j < (1 << an); j++){
                int num = 0;
                ll val = 1;
                for(int k = 0;k < an; k++){
                    if(j & (1 << k)){
                        num++;
                        val *= a[k];
                    }
                }
                if(num & 1) cnt += m / val;
                else cnt -= m / val;
            }
            ans += m - cnt;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/KirinSB/p/9568783.html

时间: 2024-08-29 14:57:11

HDU 2841 Visible Trees(容斥)题解的相关文章

hdu 2841 Visible Trees(计数问题)

题目链接:hdu 2841 Visible Trees 题目大意:一个n?m的矩阵,每个整数点上有树,人站在(0,0)点,问可以看见多少棵树. 解题思路:和uva1393是一道相同类型的题目,只不过这道题目的n比较大,不能预处理.必须用另外一种方法. 将矩阵按照(0,0)和(n,m)两天连成的直线分成两部分,分别计算,但是(n,m)这条线被计算了两次,于是减掉1. dp[i]表示这一列上有多少个点是可以被看见的,因为矩阵被对半分了,所以点的个数为m?in,同时还要计算每次看见的点会把后面的给挡住

[思维+容斥原理] 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

【容斥+素数】 HDU 2841 Visible Trees

通道 题意:求一个区间[1,m]内与i的互质的数的个数.这里1<=i<=n, 思路:对i分解质因子然后容斥 代码: #include <cstdio> #include <cstring> #include <algorithm> typedef long long LL; const int maxn = 100010; LL ans; int n,m; int fac[maxn]; int prime[maxn]; int facCnt; void ge

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互质的个数.这里的话我们可以用到分解质因数,然后用状态压

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