zzq的离散数学教室1

链接:https://www.nowcoder.com/acm/contest/96/D
来源:牛客网
题目描述


      离散数学中有种名叫“哈斯图”的东西。        在这题中,你们需要计算的是一些正整数在偏序关系“整除”下的哈斯图的边数。用大白话讲,在偏序关系“整除”下的哈斯图,就是把一个个正整数看成一个个图的节点,某些节点之间有边。连边的规则是这样的:对于任意两个正整数a和b(a<b)来说,如果b%a==0,并且不存在一个正整数c(a<c<b),使得条件b%c==0和c%a==0同时成立,那么我们就在节点a和节点b之间连一条边。        现在问题是,给你们2个数L,R(1<=L,R<=1e6)。求由L,L+1,L+2...R这R-L+1个正整数在偏序关系“整除”下的哈斯图的边数。        比如L=1,R=4,节点的组合有(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)。组合(1,2),(1,3),(2,4)可以连边。(1,4)因为中间存在c=2,不符合连边条件。所以当L=1,R=4的时候,这个哈斯图有3条边。
输入描述:
多组输入,不超过1000组数据每组数据一行,包含2个正整数L和R,中间由空格分开。
输出描述:
每组数据输出一行,包含一个整数表示哈斯图的边数。

示例1

输入
1 4
4 10
1 10

输出
3
2
11


思路:求L,R区间内所有数的素数倍落在此区间内的个数。
Code:
#include <bits/stdc++.h>
using namespace std;
const int AX = 1e6+6;
int prime[AX];
int a[AX];
int tot;
void p(){
    tot = 0;
    memset( a , 1 , sizeof(a) );
    for( int i = 2 ; i < AX ; i++ ){
        if( a[i] ){
            prime[tot ++] = i;
            for( int j = i + i  ; j < AX ; j += i ){
                a[j] = 0;
            }
        }
    }
}
int main(){
    int L ,R ;
    p();
    while( ~scanf("%d%d",&L,&R) ){
        int res = 0;
        for( int i = tot - 1 ; i >= 0 ; i -- ){
            int tmp = R / prime[i];
            if( tmp - L >= 0 ){
                res += tmp - L + 1;
            }
        }
        cout << res << endl;
    }
    return 0 ;
}

阅读更多
版权声明:本文为博主原创文章,未经博主允许也可以转载。 https://blog.csdn.net/FrankAx/article/details/79951200
个人分类: 素数
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭