标签:并查集
1 1 1 1 2 1 1 2
126
这题用到了并查集的合并知识,[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; }
标签:并查集
原文地址:http://blog.csdn.net/kirito_acmer/article/details/45672101