hdu3461 Code Lock

Problem 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

这题用到了并查集的合并知识,[1,3],[4,5]如果可以转动,那么之后如果出现[1,5]便无效了,如果没哟可移动区间,那么所有的情况是26^n,每出现一个新的可移动区间,n--,注意[1,3],[3,5]不能包括后面的[1,5],因为3重复了。这里有个技巧,就是区间合并的时候取[l-1,r],这样如[1,3],[4,5]的就能合并了。还有用快速幂的时候要注意最后的n要用__int64型,不然会出错。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
int pre[10000005];
__int64 f(int b)
{
  __int64 ans = 1,a=26,c=1000000007;
  a=a%c;
  while(b>0)
  {
   if(b%2==1)
   ans = (ans * a) % c;
   b = b/2;
   a = (a * a) % c;
  }
  return ans;
}

int find(int x)
{
	int i,j=x,r=x;
	while(r!=pre[r])r=pre[r];
	while(j!=pre[j]){
		i=pre[j];
		pre[j]=r;
		j=i;
	}
	return r;
}

int main()
{
	int n,m,i,j,ans,a,b,t1,t2;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		ans=n;
		for(i=0;i<=n;i++)pre[i]=i;
		for(i=1;i<=m;i++){
			scanf("%d%d",&a,&b);
			a--;
			t1=find(a);t2=find(b);
			if(t1==t2)continue;
			ans--;
			pre[t1]=t2;
		}
		printf("%I64d\n",f(ans)%1000000007);
	}
	return 0;
}

时间: 2024-11-12 21:50:11

hdu3461 Code Lock的相关文章

Code Lock

Code Lock Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 255 Accepted Submission(s): 114   Problem Description A lock you use has a code system to be opened instead of a key. The lock contains a

HDU 2017 Code Lock (并查集的应用+快速幂)

链接:HDU 3461 题目大意: 题目的大意是一个密码锁上有编号为1到N的N个字母,每个字母可以取26个小写英文字母中的一个.再给你M个区间[L,M],表示该区间的字母可以一起同步"增加"(从'a'变为'b'为增1,'z'增1为'a').假如一组密码按照给定的区间进行有限次的"增加"操作后可以变成另一组密码,那么我们认为这两组密码是相同的.该题的目标就是在给定N.M和M个区间的前提下计算有多少种不同的密码. 根据题意,如果一个可调整的区间都没有的话,答案应该是26

HDU 3461 Code Lock(并查集的应用+快速幂)

* 65536kb,只能开到1.76*10^7大小的数组.而题目的N取到了10^7,我开始做的时候没注意,用了按秩合并,uset+rank达到了2*10^7所以MLE,所以貌似不能用按秩合并. 其实路径压缩也可以不用.............  题目的大意: 一个密码锁上有编号为1到N的N个字母,每个字母可以取26个小写英文字母中的一个.再给你M个区间[L,M],表示该区间的字母可以一起同步"增加"(从'a'变为'b'为增1,'z'增1为'a').假如一组密码按照给定的区间进行有限

HDU 3461 - Code Lock

Problem 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 c

HDU 3461 Code Lock(并查集+二分求幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3461 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

Code Lock HDU 3461

给定由N个字母组成的密码锁,如[abcdef]每一位字母都可以转动,转动该字母时,将变成它的下一个字母,如'a'转动后是b,x转动后是y, 接着给定M个区间,每次转动给定区间内的所有字母,如密码锁[abcdef],给定区间[1,3]转动这个区间一次后变为[bcddef]; 题解:  要是用并查集蒙的话,有可能就很容易的蒙出来了,但是要是证明的话还是有点难度的.... 待续: Problem Description A lock you use has a code system to be op

hdu Code Lock

题意是说有N个字母组成的密码锁, 如[wersdfj],   每一位上的字母可以转动, w可转动变成x, z变成a.但是题目规定, 只能同时转动某个区间上的所有字母, 如[1,3], 那么第1到第3个的所有字母要同时转动,那么[ wersdfj ]经过一次操作就变成 [ xfssdfj ].    一共有M 个区间是可以操作的. 题目还规定:If a lock can change to another after a sequence of operations, we regard them

hdu 3461 Code Lock(并查集)

想不到这还可以用并查集解,不过后来证明确实可以…… 题意也有些难理解—— 给你一个锁,这个所由n个字母组成,然后这个锁有m个区间,每次可以对一个区间进行操作,并且区间中的所有字母要同时操作.每次操作可以将区间中所有字母+1.即把a变成b,把z变成a. 举个例子,比如有一个锁,由abcdef组成,前三个字母abc是一个区间,第四五个字母de是一个区间,那么如果对abc操作一次,则获得新锁bcddef,再对de区间操作一次,得bcdeff.但是,最后一个字母f是不能操作的. 如果一把锁通过对可操作区

并查集练习1

举头望明月,低头敲代码... 推荐学习地址:http://www.cnblogs.com/cyjb/p/UnionFindSets.html 简单: hdu1213 How Many Tables:新手必秒 1 #include<cstdio> 2 const int N=1001; 3 int f[N]; 4 void init(int n){ 5 for(int i=1;i<=n;++i) 6 f[i]=i; 7 } 8 int fin(int x){ 9 if(x!=f[x])f[