zoukankan      html  css  js  c++  java
  • HDU 3461 Code Lock(并查集)

    很好的一个题,思想特别6

    题意:给你小写字母个数n,每个字母可以向上翻动,例如:d->c,a->z。然后给你m对数(L,R)(L<=R),表示[L,R]之间可以同时向上翻动,且翻动后是相同的类型。问你最后可以出现多少种不同的类型。

    例如:abcabc只给你[1,3],那么abcabc==zababc(代表相同类型)

    首先答案是是26^(n-m+k),而我们只需要找到k就好了。而k只能有一种情况才会出现,就是:[1,3]与[4,6]出现后[1,6]再出现,这样k就加一个。而[1,3]与[3,6]出现后[1,6]出现,k不会加一(因为是区间关系)。这样我们就离散化后,对[L-1,R]使用并查集就好。

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<stdlib.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define eps 1E-8
    /*注意可能会有输出-0.000*/
    #define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
    #define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
    #define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
    #define mul(a,b) (a<<b)
    #define dir(a,b) (a>>b)
    typedef long long ll;
    typedef unsigned long long ull;
    const int Inf=1<<28;
    const double Pi=acos(-1.0);
    const ll Mod=1000000007;
    const int Max=1010;
    int fat[Max];
    map<int,int> mp;//离散化
    struct node
    {
        int lef,rig;
    }lock[Max];
    void init(int m)
    {
        for(int i=0;i<=m;++i)
            fat[i]=i;
        return;
    }
    ll Ftp(ll num,int n)
    {
        ll sum=1ll;
        while(n)
        {
            if(n&1)
                sum=(sum*num)%Mod;
            num=(num*num)%Mod;
            n>>=1;
        }
        return sum;
    }
    int Find(int x)
    {
        if(x==fat[x])
            return fat[x];
        return fat[x]=Find(fat[x]);
    }
    int Union(int x,int y)
    {
        int x1=Find(x);
        int y1=Find(y);
        if(x1==y1)
            return 0;
            fat[x1]=y1;
        return 1;
    }
    ll Solve(int n,int m)
    {
        for(int i=0;i<m;++i)
            n-=Union(mp[lock[i].lef],mp[lock[i].rig]);//关键
        return Ftp(26ll,n);
    }
    int main()
    {
        //std::ios::sync_with_stdio(false);
        int n,m;
        while(~scanf("%d %d",&n,&m))
        {
            init(m<<1);
            mp.clear();
            for(int i=0;i<m;++i)
            {
                scanf("%d %d",&lock[i].lef,&lock[i].rig);
                mp[--lock[i].lef]=1;
                mp[lock[i].rig]=1;
            }
            int coun=0;
            for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it)
                it->second=coun++;//map离散化
            printf("%I64d
    ",Solve(n,m));
        }
        return 0;
    }
  • 相关阅读:
    python全栈开发day76-博客主页
    python全栈开发day75-用户注册页面ajax实现,用户头像上传、预览、展示
    python全栈开发day74-普通验证码和滑块验证码
    python全栈开发day73-Django认证系统
    python全栈开发day72-django之Form组件
    python全栈开发day70-Django中间件
    python全栈开发day69-cookie、session
    python全栈开发day68-ORM操作:一般操作、ForeignKey操作、ManyToManyField、聚合查询和分组查询、F查询和Q查询等
    选择排序
    冒泡排序
  • 原文地址:https://www.cnblogs.com/zhuanzhuruyi/p/5890495.html
Copyright © 2011-2022 走看看