HUD 3461 codelock (并查集+快速幂)

Description:

A lock you use has a code system to be opened instead of a key. The lock contains a sequence of wheels. Each wheel has the 26 letters of the English alphabet 'a' through 'z', in order. If you move a wheel up, the letter it shows changes to the next letter in the English alphabet (if it was showing the last letter 'z', then it changes to 'a'). 
At each operation, you are only allowed to move some specific subsequence of contiguous wheels up. This has the same effect of moving each of the wheels up within the subsequence. 
If a lock can change to another after a sequence of operations, we regard them as same lock. Find out how many different locks exist? 

Input

There are several test cases in the input. 

Each test case begin with two integers N (1<=N<=10000000) and M (0<=M<=1000) indicating the length of the code system and the number of legal operations. 
Then M lines follows. Each line contains two integer L and R (1<=L<=R<=N), means an interval [L, R], each time you can choose one interval, move all of the wheels in this interval up. 

The input terminates by end of file marker. 

Output

For each test case, output the answer mod 1000000007

Sample Input

1 1
1 1
2 1
1 2

Sample Output

1
26

 

题意

有一个长n的字符串锁,求这个锁有多少种不同的解锁方式,这个锁有若干个区间能够转动,两个能通过转动互相到达的情况属于同一种解锁方式。比如长度为1,如果没有区间就有'a'~'z'26中解锁方式。如果有一个转动区间[1,1],那么'a'->'b'->...'z',所以就只要1种解锁方式啦。

很明显答案是26^k,主要就是求k。我们会发现如果有3个区间[1,4],[5,10]和[1,10]实际上是会等于两个区间[1,4]和[5,10]的。其实想到这一点应该就能知道trick点在于有些区间其实是无效的了,那么怎么处理是否当前区间有效呢?只需要用并查集判他们是否在同一集合即可,同时我们只要到[1,1]这样的区间也是有意义的那么我们变成l与r+1合并即可。答案的k就是n-有效区间个数。

对样例1的解释:


1 1
1 1
表示只有一个字母,这个字母可以是a.....z, 1代表下面只有一个操作区间,就是1 1, 
当这个字母是a时, 它经过1 1这个操作区间进行有限次的“增加”后,可以变成b,c,d....z,那么a和b....z就是同一种锁,
当这个字母是b时, 它经过1 1这个操作区间进行有限次的“增加”后,可以变成a,  c,d....z,因为a,....z已经是同一种锁了,,如果这个字母是c....
所以只有 1 种不同锁;


如果只有一个字母,,,没有可操作区间,即N = 1, M = 0, 那么
如果这个字母是a就不能变成b....z,所以a和b...z就不是同种锁,如果b,同理,,,所以总共有26个不同的锁;


样例 2


2 1
1 2
有两个字母组成, 一个操作区间,就是1到2;
当这两个字母是ab,在可操作区间1 2,它可以变成bc,cd,.....za;那么ab和bc,cd,.....za就是同种锁
当这两个字母是bc时, 当这两个字母是cd时......等等,这都和当字母是ab时相同,这算一种锁;
当字母是ac时,字母ac 和 bd.......zb都是属于同种锁, 
当字母是ad时,当字母是等等,

所以有26种不同的

 

样例 3

 

2 2

1 1

2 2

两个字母,两个区间

当移动区间 1 1 时,当这两个字母是ab 时,  变成 bb, cb, db........zb这是一种锁

当我移动区间2 2时,当这两个字母是ab时,变成aa,,,,ac,ad,ae    ......az;

所以 ab..................zb和  ab..................az属于同锁,以及他们的变换,

最终只会有一种不同锁,即只有一个锁

AC代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int MOD=int(1e9)+7;
using namespace std;
ll n,m,t;
int i,j,k,l;
int ans,sum,num,cnt;
char a[200010];
int pre[10000010];
int Find(int x)
{
    int r=x;
    while(pre[r]!=r)
        r=pre[r];
    return r;
}

bool mix(int a,int b)
{
    int x=Find(a);
    int y=Find(b);
    if(x==y)
    return false;
      pre[x]=y;
    return true;

}

ll pow(int x)
{
    ll res=1;
    for(i=0 ;i<x;i++)
    {
        res*=26;
        res%=MOD;
    }
    return res;
}

int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        for(i=0;i<=10000001;i++)
            pre[i]=i;
        cnt=0;
        int l,r;
        for(i=0;i<m;i++)
        {
            scanf("%d %d",&l,&r);
            if(mix(l,r+1))
                cnt++;
        }
        printf("%lld\n",pow(n-cnt));
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值