zoukankan      html  css  js  c++  java
  • 开学考试题1:seg Mushroom的区间(并查集)

    题目:

    暴搜30分

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100005
    int n,m,ans=0,maxn;
    bool vis[1<<21];
    struct node{
        int l,r;
    }v[N];
    int read()
    {
        int x=0,fl=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') fl=-1; ch=getchar(); }
        while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
        return x*fl;
    }
    int change(int x,int l,int r)
    {
        for(int i=l;i<=r;++i) x=x^(1<<(n-i));
        return x;
    }
    void dfs(int pos,int x)
    {
        if(ans>=maxn) { printf("%d
    ",maxn); exit(0); }
        if(pos>m){//printf("x:%d
    ",x);
            if(!vis[x]) ans++,vis[x]=true; 
            return ;
        }
        dfs(m+1,x);
        for(int i=pos;i<=m;i++){
            int tmp=change(x,v[i].l,v[i].r);
            dfs(i+1,tmp);
        }
    }
    int quick_pow(int a,int k)
    {
        int ans=1;
        while(k){ if(k&1) ans*=a; a*=a; k>>=1; }
        return ans;
    }
    int main()
    {
        freopen("seg.in","r",stdin);
        freopen("seg.out","w",stdout);
        n=read(); m=read();
        for(int i=1;i<=m;++i) v[i].l=read(),v[i].r=read();
        maxn=quick_pow(2,n);
        dfs(1,0);
        printf("%d
    ",ans);
        return 0;
    }
    /*
    3 3
    1 1
    2 2
    3 3
    */
    View Code

    分析:

    如果每一个点都可以翻转的话,就是2^n种,再推广一下,如果不考虑重复的话,就是2^m种。

    但是像 1 2 , 3 4,1 4,这三个区间,第三个明显可以由第一个和第二个拼凑而来,就会多算一种。

    考虑删除无用区间:并查集合并区间

    具体步骤:将一个区间的左端点和右端点+1放在一起,如果已经是同一个father了,就说明已经合并在一起了,即为无用区间。(father同,说明左端点和右端点早已连在了同一个点上)

    (其实可以不用排序,因为1 2,1 4 是可以凑出3 4的,不一定要小的凑大的)

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100005
    #define ll long long
    const int mod=1e9+7;
    int n,m,fa[N],tmp[N];
    ll ans=0;
    struct node{
        int l,r;
    }v[N];
    bool cmp(const node &a,const node &b)
    {
        return (a.r-a.l)<(b.r-b.l);
    }
    int read()
    {
        int x=0,fl=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') fl=-1; ch=getchar(); }
        while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
        return x*fl;
    }
    
    ll quick_pow(int a,int k)
    {
        ll ans=1;
        while(k){ if(k&1) ans=(ll)ans*a%mod; a=(ll)a*a%mod; k>>=1; }
        return ans;
    }
    int find(int x)
    {
        if(x==fa[x]) return x;
        return fa[x]=find(fa[x]);
    }
    int main()
    {
        freopen("seg.in","r",stdin);
        freopen("seg.out","w",stdout);
        n=read(); m=read();
        
        for(int i=1;i<=n+1;i++) fa[i]=i;
        for(int i=1;i<=m;++i) v[i].l=read(),v[i].r=read();
        //sort(v+1,v+1+m,cmp);
        int cnt=m;
        for(int i=1;i<=m;i++){
            int f1=find(v[i].l),f2=find(v[i].r+1);
            if(f1==f2) cnt--;
            else fa[f1]=f2;
        }
        printf("%d
    ",cnt);
        ans=quick_pow(2,cnt);
        printf("%lld
    ",ans);
        return 0;
    }
    /*
    
    
    3 3
    3 3
    1 3
    1 2
    */
  • 相关阅读:
    单表查询
    多表查询
    (Redis基础教程之七)如何使用Redis中的Hashes
    (Python基础教程之三)Python代码中添加注释
    (Python基础教程之二)在Sublime Editor中配置Python环境
    (Redis基础教程之六)如何使用Redis中的List
    (Redis基础教程之五)如何在Redis中操作字符串
    (Redis基础教程之一)如何在Ubuntu 18.04上安装和保护Redis
    Redis数据类型简介(十分钟快速学习Redis)
    如何使用,操作Redis数据库
  • 原文地址:https://www.cnblogs.com/mowanying/p/11478124.html
Copyright © 2011-2022 走看看