蓝桥杯国赛备赛DAY2

数论:
1.素数(质数)

①定义法:O(n)
n>=2 && i<=n-1

②性质法: O(sqrt(n))
成对出现
若d能整除n,那么n/d也能整除n
d 和n/d为一对
那么我们只要枚举到较小的即可
答案:d<=n/d,


dd<=n PS:这种写法不推荐 若n接近int最大值,那么dd有可能存在溢出风险

d<=sqrt(n) PS:这种写法不推荐 因为没次都要调用一次函数,效率低。

2.约数
与质数相对
做法与质数一样

并查集:
836. 合并集合
题目链接

与之前学的kruscal是一个道理的

#include<iostream>

using namespace std;

const int N=100000+10;

int n,m;
int father[N];

int find(int x){
    
    
    return father[x]==x?x:father[x]=find(father[x]);
}

void my_union(int a, int b){
    
    
    int xx=find(a);
    int yy=find(b);
    if(xx!=yy){
    
    
        if(yy>xx){
    
    
            father[yy]=xx;
        }else{
    
    
            father[xx]=yy;
        }
    }
}

int main(){
    
    
    cin>>n>>m;
    for(int i=1;i<=n;i++){
    
    
        father[i]=i;
    }
    
    while(m--){
    
    
        char s[2];
        int a,b;
        cin>>s>>a>>b;
        if(s[0]=='M'){
    
    
            my_union(a,b);
        }else{
    
    
            if(find(a)==find(b)){
    
    
                cout<<"Yes"<<endl;
            }else{
    
    
                cout<<"No"<<endl;
            }
        }
    }
        
    return 0;
}

并查集的扩展应用:
837. 连通块中点的数量
题目链接

在并查集原有代码的基础上改造。

#include<iostream>

using namespace std;

const int N=100000+10;

int n,m;
int father[N];
int se[N];

int find(int x){
    
    
    return father[x]==x?x:father[x]=find(father[x]);
}

void my_union(int a, int b){
    
    
    int xx=find(a);
    int yy=find(b);
    if(xx!=yy){
    
    
        if(yy>xx){
    
    
            se[xx]+=se[yy];
            father[yy]=xx;
        }else{
    
    
            se[yy]+=se[xx];
            father[xx]=yy;
        }
    }
}

int main(){
    
    
    cin>>n>>m;
    for(int i=1;i<=n;i++){
    
    
        father[i]=i;
        se[i]=1;
    }
    
    while(m--){
    
    
        char s[5];
        int a,b;
        cin>>s;
        if(s[0]=='C'){
    
    
            cin>>a>>b;
            my_union(a,b);
        }else if(s[1]=='1'){
    
    
            cin>>a>>b;
            if(find(a)==find(b)){
    
    
                cout<<"Yes"<<endl;
            }else{
    
    
                cout<<"No"<<endl;
            }
        }else{
    
    
            cin>>a;
            int f=find(a);
            cout<<se[f]<<endl;
        }
    }
        
    return 0;
}

240.食物链 并查集 练习题

ps:dp的递归形式 - 记忆化搜索 (区间dp写成递归比较好理解)

猜你喜欢

转载自blog.csdn.net/BOWWOB/article/details/109303147