• P1621 集合


    传送门

    解题思路

    因为是在[a,b]范围内将两个拥有大于等于P的公共质因数的整数进行合并,关于质数的操作我们很容易会联想到素数筛,实际上就是这样,我们先通过欧拉筛,然后我们找到第一个大于等于a的质数,然后将[a,b]范围内的该质数的倍数进行合并操作,最后从a到b数一下有多少个分类即可

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define endl "
    "
    
    const int N = 100005;
    
    int primes[N];
    bool vis[N];
    int b,a,p;
    int fa[N];
    
    
    void init() {
    	for(int i = 1;i < N; ++i) fa[i] = i;
    }
    
    void get_prime(int n) {
    	vis[0] = vis[1] = true;
    	for(int i = 2;i <= n; ++i) {
    		if(!vis[i]) 
    			primes[++primes[0]] = i;
    		for(int j = 1;j <= primes[0] && primes[j] * i <= n; ++j) {
    			vis[primes[j] * i] = true;
    			if(i % primes[j] == 0) break;
    		}
    	}
    }
    
    
    int find(int x) {
    	int t = x;
    	while(t != fa[t]) {
    		t = fa[t];
    	}
    	while(x != fa[x]) {
    		int temp = fa[x];
    		fa[x] = t;
    		x = temp;
    	}
    	return x;
    }
    
    void merge(int l,int r) {
    	l = find(l);
    	r = find(r);
    	if(l != r) {
    		fa[r] = l;
    	}
    }
    
    int main()
    {
    	scanf("%d%d%d",&a,&b,&p);
    	init();
    	get_prime(b);
    	int i = lower_bound(primes+1,primes+1+primes[0],p) - primes;
    //	while(primes[i] < a) i++;
    	for(;i < primes[0] && primes[i] <= b; ++i) {
    		int k = primes[i];
    		for(int j = 1;j <= b && j * k <= b; ++j) {
    				merge(k,j * k);
    		}
    	}
    	set<int> ans;
    	for(i = a; i <= b; ++i) {
    //		printf("i = %d  find() = %d
    ",i,find(i));
    		ans.insert(find(i));
    	}
    	printf("%d
    ",ans.size());
    	return 0;
    }
    /*
    10 20 3
    */ 
    
  • 相关阅读:
    Highlighting Scatter Charts in Power BI using DAX
    在 Visio 中创建组织结构图
    Power BI Desktop 2020年7月功能摘要
    Power BI Calculation Group
    Vue中的路由以及ajax
    Vue的基本语法和常用指令
    洛谷P1525关押罪犯
    洛谷P2411 【[USACO07FEB]Silver Lilypad Pond S】
    洛谷P1776 宝物筛选(二进制优化多重背包)
    P3275 [SCOI2011]糖果
  • 原文地址:https://www.cnblogs.com/Mangata/p/14729078.html
Copyright © 2020-2023  润新知