完全没思路,题目也没看懂,直接参考大牛们的解法。

http://www.myexception.cn/program/723825.html

题意是说有N个字母组成的密码锁,如[wersdfj],每一位上的字母可以转动,变成字母表中的下一位。 如w可转动变成x,z变成a。但是题目规定,只能同时转动某个区间上的所有字母,如[1,3], 那么第1到第3个的所有字母要同时转动, 那么[wersdfj]经过一次操作就变成[xfssdfj].一共有M个区间是可以操作的。

经过可操作区间进行的操作得到的所有情况,都是同一个的。 也就是指不管我在题目给出的某一个区间怎么转动,其它位上的字母都不变,它仍视为同一种。

假如原本是[abc],给出可操作区间[1,2],即我可以转动第一个、第二个字母,当然是同时转动的。 由于[1,2]区间情况所能变化得到的,都视为同一种。我不妨固定第一个字母,就为a,其余25个字母可有a变化得到。 那么第二位上的字母,就可以有26种可能,也就是[1,2]区间可能的情况有26种,再加上独立的第3个字母有26种可能,总共有26^2种。

也就是说,有n个字母组成的密码锁,原本会有26^n种。如果有一个可操作区间,那么会有26次变换。 相当于这个操作区间就减少了原来的26种,总的也就变为26^(n-1)。 也就是现在我们要统计有多少个可操作区间,若为cnt,则答案即为26^(n-cnt),这当然要用到快速幂。

至于怎么求区间个数,采用的是区间合并的方法,给出一个区间[L,R],若可以合并,则cnt++。

不过这里有一个情况要注意:

假设有区间[1,3],[3,5],[1,5],如果按照Union(L, R)来算, 那么[1,3],[3,5]可以合并,cnt为2, 但[1,5]因为已经属于同一个集合,则不合并。那么得到两种可操作区间。 但实际上是有3中可操作区间的,因为1~3, 3~5是有重叠了3的两个区间,所以1~5区间的情况不包括在前两个区间的情况内。

如果是[1,3],[4,5],[1,5],如果合并的话,cnt为3,但实际就只有两种情况,因为最后一种的转动情况包含在了前两种转动的情况之内了。

这里大牛们就想出了一个解决办法:

合并[L-1,R]或者[L,R+1]。

如上述区间[1,3],[3,5],[1,5],[1,3]合并的是[0,3],[3,5]合并的是[2,5],[1,5]合并的是[0,5],这样cnt=3;

如果是[1,3],[4,5],[1,5],那么cnt=2;

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm> using namespace std; const int maxn=;
const int mod=+;
int father[maxn];
int n,m; void init(){
for(int i=;i<=n;i++)
father[i]=i;
} int find_root(int x){
if(father[x]!=x)
father[x]=find_root(father[x]);
return father[x];
} bool Union(int a,int b){
int x=find_root(a);
int y=find_root(b);
if(x==y)
return false;
father[y]=x;
return true;
} //注意要long long ,即使a(26)也要定义成long long
long long quickPow(long long a,int b){
long long ans=;
while(b>){
if(b&){
ans=(ans*a)%mod;
}
a=a*a%mod;
b=b>>;
}
return ans;
} int main()
{
int l,r;
while(scanf("%d%d",&n,&m)!=EOF){
int cnt=;
init();
for(int i=;i<=m;i++){
scanf("%d%d",&l,&r);
l--;
if(Union(l,r))
cnt++;
}
long long ans=quickPow(,n-cnt);
printf("%I64d\n",ans);
}
return ;
}

HDU 3461 Code Lock(并查集,合并区间,思路太难想了啊)的更多相关文章

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3461 A lock you use has a code system to be opened in ...

  2. hdu 3461 Code Lock 并查集(有点难想到)★★

    #include<stdio.h> #include<math.h> ]; int count; #define mod 1000000007 int find(int x) ...

  3. HDU 3461 Code Lock(并查集)

    很好的一个题,思想特别6 题意:给你小写字母个数n,每个字母可以向上翻动,例如:d->c,a->z.然后给你m对数(L,R)(L<=R),表示[L,R]之间可以同时向上翻动,且翻动后 ...

  4. hdu 3461 Code Lock(并查集)2010 ACM-ICPC Multi-University Training Contest(3)

    想不到这还可以用并查集解,不过后来证明确实可以…… 题意也有些难理解—— 给你一个锁,这个所由n个字母组成,然后这个锁有m个区间,每次可以对一个区间进行操作,并且区间中的所有字母要同时操作.每次操作可 ...

  5. HDU 3461 Code Lock(并查集的应用+高速幂)

    * 65536kb,仅仅能开到1.76*10^7大小的数组. 而题目的N取到了10^7.我開始做的时候没注意,用了按秩合并,uset+rank达到了2*10^7所以MLE,所以貌似不能用按秩合并. 事 ...

  6. HDU 3461 思维+并查集

    Code Lock 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3461 Problem Description A lock you use has ...

  7. hdu 3461 Code Lock

    http://acm.hdu.edu.cn/showproblem.php?pid=3461 并差集和幂取模 这道题主要是求不可操作区间. #include <cstdio> #inclu ...

  8. HDU 4313 Matrix(并查集)

    http://acm.hdu.edu.cn/showproblem.php?pid=4313 题意: 给出一棵树,每条边都有权值,其中有几个点是特殊点,现在破坏边还使得这几个特殊点互相不可达,需要使得 ...

  9. HDU 6109 数据分割 并查集,SET

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6109 题意:中文题面 解法:每次都贪心地尝试将尽量多的条件放进当前这组,遇到第一个与已有条件冲突时,就 ...

随机推荐

  1. Codevs 1231 最优布线问题

    题目描述 Description 学校需要将n台计算机连接起来,不同的2台计算机之间的连接费用可能是不同的.为了节省费用,我们考虑采用间接数据传输结束,就是一台计算机可以间接地通过其他计算机实现和另外 ...

  2. sicily 1027 MJ, Nowhere to Hide 字符串匹配与排序

    1027. MJ, Nowhere to Hide Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description On BBS, th ...

  3. FPGA使用技巧

    1 IOB       为了保证FPGA输入输出接口的时序,一般会要求将输入管脚首先打一拍再使用,输出接口也要打一拍再输出FPGA.将信号打一拍的方法是将信号通过一次寄存器,而且必须在IOB里面的寄存 ...

  4. seajs使用记录

    关于base的默认路径: [官方说明]: 模块系统的基础路径即 base 的默认值,与 sea.js 的访问路径相关: 如果 sea.js 的访问路径是: http://example.com/ass ...

  5. linux命令详解之useradd命令

    useradd命令使用方法,还包括用户账号的添加.删除与修改.用户口令的管理.用户组的管理方法. Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申 ...

  6. Docs list

    http://www.deansys.com/doc/ldd3/index.html Github中文文档: http://www.worldhello.net/gotgithub/03-projec ...

  7. 开发流程习惯的养成—TFS简单使用

    才开始用,所以是个很基础的介绍,欢迎大家一起交流学习 一.追本溯源 讲到开发流程,还要从敏捷开始,因为敏捷才有了开发流程的重视,整个流程也是按照敏捷的思想进行的,这里不再叙述敏捷的定义 敏捷的流程(个 ...

  8. java中封装

    .什么是封装? 封装就是将属性私有化,提供公有的方法访问私有属性. 做法就是:修改属性的可见性来限制对属性的访问,并为每个属性创建一对取值(getter)方法和赋值(setter)方法,用于对这些属性 ...

  9. jetty 8.x, 9.x无法加载jstl的PWC6188问题

    参考: cannot load JSTL taglib within embedded Jetty server:http://stackoverflow.com/questions/2151075/ ...

  10. c++数组-矩阵的转置

    #include <iostream> using namespace std; int main(){ ][]={{,,},{,,}}; ][]; ;j<;j++){ ;i< ...