标签:
中文题目:
Tina Town 的镇中有一块表面平整光滑的大石头, 当人面向它走进时, 石头的表面就会亮起, 显示出它的用途. 这块石头是前人留下来的东西,是Tina Town算力和控制系统的核心, 同时它也可以显示Tina Town的大小事和行人关注的内容,也可以作为公共的计算机使用 ,极大地方便了人们的生活(特别是上街忘带终端的人们啦). Tina和Town在这块大石头上玩一个游戏. 石头上首先显示出了1到n排列的n个数,Town则随机交换了一些数, 然后Town通过宏将这个交换的过程记录下来了. Town 问 Tina: 你知道执行几次这个宏, 这些数会恢复最早的排列嘛? Tina是一个蠢蠢的女孩子, 当然不知道啦, 于是她想向你请教呢.
来自官方题解:
给出一个置换,求它的循环长度。数据范围 3\times 10^63×10?6??。
其实没有什么好说的,就分解成循环求长度的最小公倍数就好了。对于这个模数要用unsigned int存,这个最小公倍数的求法不能用欧几里得,直接每次分解质因数,用线性筛预处理一下就好了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<set> 6 #include<map> 7 #include<cmath> 8 #include<stdlib.h> 9 using namespace std; 10 #define ll long long 11 #define N 3000006 12 #define MOD 3221225473 13 int n; 14 int a[N]; 15 int vis[N]; 16 int cou[N]; 17 inline int sca() //输入外挂 18 { 19 int res=0,ch,flag=0; 20 if((ch=getchar())==‘-‘) 21 flag=1; 22 else if(ch>=‘0‘&&ch<=‘9‘) 23 res=ch-‘0‘; 24 while((ch=getchar())>=‘0‘&&ch<=‘9‘) 25 res=res*10+ch-‘0‘; 26 return flag?-res:res; 27 } 28 int main() 29 { 30 int t; 31 scanf("%d",&t); 32 while(t--) 33 { 34 scanf("%d",&n); 35 for(int i=1;i<=n;i++) 36 { 37 a[i]=sca(); 38 vis[i]=0; 39 cou[i]=0; 40 } 41 42 for(int i=1;i<=n;i++) 43 { 44 if(vis[i]) continue; 45 int len=1; 46 int k=a[i];//k用来查找长度 47 while(k!=i)//如果当前的数与原来的位置不一样,则长度加1 48 { 49 len++; 50 vis[k]=1; 51 k=a[k]; 52 } 53 for(int j=2;j*j<=len;j++)//这边用来计算最小公倍数,不能用lcm,因为这里是单个数 54 { 55 int c=0; 56 if(len%j==0)//如果可以分解质因数的话,则连续分解 57 { 58 while(len%j==0) 59 { 60 c++; 61 len=len/j; 62 } 63 cou[j]=max(cou[j],c);//记录这个质因数的个数 64 } 65 } 66 if(len>1) cou[len]=max(cou[len],1);//记住这里要加上,比如说10来分解质因数,最后剩下5(10/2=5),则cou【5】也要算进去 67 } 68 69 ll ans=1; 70 for(int i=2;i<=n;i++)//这边计算最小公倍数 71 { 72 for(int j=0;j<cou[i];j++) 73 ans=ans*i%MOD; 74 } 75 printf("%I64d\n",ans); 76 } 77 return 0; 78 }
hdu 5392 Infoplane in Tina Town(数学)
标签:
原文地址:http://www.cnblogs.com/UniqueColor/p/4733462.html