zoukankan      html  css  js  c++  java
  • [SDOI2008] 仪仗队

    题目类型:莫比乌斯反演/欧拉函数??

    传送门:>Here<

    题意:有一个(N*N)的方阵,问左下角那个人可以看到几个人?(光沿直线传播)

    解题思路

    考虑什么时候一个人会看不见?那就是和别的一条视线重合的时候。又由于线段的另一个端点是确定的,因此视线会重合当且仅当

    斜率相同。

    因此题目就是在问我们有几个不同的斜率。设一个人的位置为((i,j)),则他的斜率是(dfrac{j}{i})。要使斜率不同,其实也就

    是此分数不得被约分。为什么?因为如果能被约分就对应另外一个人的坐标了!

    因此题目也就是转化为求在(N)的范围内互质整数对的个数(互质则不能约分)。因此莫比乌斯反演即可

    然而我们默认了原点是((0,0)),因此先将那块右上角求好,让现在的((1,1))去当((0,0)),然后加上((0,1))((1,0))则两个

    点。注意,这时候我们已经把(N)减了1了。

    反思

    这题的关键在于想怎样会看不到,而不是怎样才能看到。有时正着想不出来,反着想更简单

    另外,考虑边界条件的时候常常涉及到+1-1,这时候要大胆猜想,小心验证。

    Code

    筛莫比乌斯函数的时候要记得判断超界。(就是这样(RE)的)

    /*By DennyQi 2018*/
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int MAXN = 400010;
    const int INF = 1061109567;
    inline int Max(const int a, const int b){ return (a > b) ? a : b; }
    inline int Min(const int a, const int b){ return (a < b) ? a : b; }
    inline int read(){
        int x = 0; int w = 1; register char c = getchar();
        for(; c ^ '-' && (c < '0' || c > '9'); c = getchar());
        if(c == '-') w = -1, c = getchar();
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x<<3) + (x<<1) + c - '0'; return x * w;
    }
    int N,ans;
    int mu[MAXN],prime[MAXN],b[MAXN],tot;
    inline void getMobius(){
    	mu[1] = 1;
    	for(int i = 2; i <= N; ++i){
    		if(!b[i]){
    			prime[++tot] = i;
    			mu[i] = -1;
    		}
    		for(int j = 1; j <= tot; ++j){
    			if(i * prime[j] > N) break;
    			b[i * prime[j]] = 1;
    			if(i % prime[j] == 0){
    				mu[i * prime[j]] = 0;
    				break;
    			}
    			mu[i * prime[j]] = -mu[i];
    		}
    	}
    }
    int main(){
    	N = read()-1;
    	if(N <= 0){
    		printf("0");
    		return 0;
    	}
    	getMobius();
    	for(int i = 1; i <= N; ++i){
    		ans += mu[i] * (N/i) * (N/i);
    	}
    	printf("%d", ans+2);
    	return 0;
    }
    
  • 相关阅读:
    [Android6.0][RK3399] 双屏异显代码实现流程分析(二)【转】
    uboot中添加自己的命令【转】
    android压力测试命令monkey详解【转】
    T-sql语句修改数据库逻辑名、数据库名、物理名(sql2000)
    sql查询与修改数据库逻辑文件名,移动数据库存储路径
    如何修改SQL Server 2000的数据库逻辑与物理名称
    你是否也忘了刷新视图?
    单点登录CAS-Demo
    SQL Case when 的使用方法 (转)
    因为数据库正在使用,所以无法获得对数据库的独占访问权(转)
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9748335.html
Copyright © 2011-2022 走看看