• 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
    ",res);
        }
        return 0;
    }
  • 相关阅读:
    Linux下使用Eclipse 远程调试
    关于Mysql分区和分表
    Mysql点滴
    父窗口与iFrame之间调用方法和元素
    pl/sql developer安装使用即时客户端
    Java的四大基础特性
    Get与Post的小知识
    ibatis 中 $与#的区别
    Eclipse安装配置Maven
    Git学习
  • 原文地址:https://www.cnblogs.com/WABoss/p/5182498.html
Copyright © 2020-2023  润新知