zoukankan      html  css  js  c++  java
  • hdu 2841(容斥原理+状态压缩)

    Visible Trees

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


    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
    题意:在(0,0)点观察一个起始点为(1,1)点的n*m矩阵,矩阵每个位置都有树,问最多能看到多少棵树??
    假设在(0,0)点可以看到点(A,B),那么(k*A,k*B)(k>1)都是看不到的,所以在这条斜率上能看到的两个点必然互质。所以题目就变成了在[1,m]内与x(1<=x<=n)互质的数有多少个了。这时我们的第一想法是欧拉函数,但是不行,因为是[1-m]范围内,只有当x==m时才可以用,所以我们将x分解质因数,假设 x=p1e1p2e2..那么在[1,m]与x不互质的数必然是pi的倍数,所以我们这里就要用容斥原理来解了。给出状压版本。
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    typedef long long LL;
    
    int e[50];
    
    void devide(int n,int &id){
        for(int i=2;i*i<=n;i++){
            if(n%i==0){
                e[id++] = i;
                while(n%i==0) n/=i;
            }
        }
        if(n>1) e[id++] = n;
    }
    int main()
    {
        int n,m;
        int tcase;
        scanf("%d",&tcase);
        while(tcase--){
            scanf("%d%d",&n,&m);
            LL ans = m;
            for(int i=2;i<=n;i++){
                int id = 0;
                devide(i,id);
                int sum = 0;
                for(int j=1;j<(1<<id);j++){
                    int cnt = 0,l=1;
                    for(int k=0;k<id;k++){
                        if((j>>k)&1){
                            cnt++;
                            l*=e[k];
                        }
                    }
                    if(cnt&1){
                        sum+=m/l;
                    }else{
                        sum-=m/l;
                    }
                }
                ans+=(LL)(m-sum);
            }
            printf("%lld
    ",ans);
        }
    }
  • 相关阅读:
    HTTP/2之服务器推送(Server Push)最佳实践
    相似人群画像算法
    Linux也有后悔药,五种方案快速恢复你的系统
    IPv6原理、应用与实践
    护航者,腾讯云: 2017年度游戏行业DDoS态势报告—回溯与前瞻
    放大倍数超5万倍的Memcached DDoS反射攻击,怎么破?
    Unity引擎与C#脚本简介
    腾讯云Redis混合存储版重磅推出,万字长文助你破解缓存难题!
    拒绝平庸,以程序员的名义定义新桌面!
    腾讯云EMR大数据实时OLAP分析案例解析
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5541550.html
Copyright © 2011-2022 走看看