莫名其妙的错了
练习2:置换的“周期”
题目描述
N个数的全排列有N!种,比如5个数的排列有5!=120种。但是,前面的置换( 3 4 5 2 1 )我们看到,置换6次后,数列就还原了。
显然,置换( 3 4 5 2 1 )只能得到6个不同的排列,或称这个置换的周期是6。
当N比较大时,周期有可能回很大!
输入格式
第一行1个正整数:N,范围在[1, 1000000],表示字符串长度。
第二行:有N个整数,为1到N的一个全排列,表示一个置换。
输出格式
一行,1个数,表示置换的周期数。注意输出的是:答案%1000007。
输入/输出例子1
输入:
5
5 3 2 1 4
输出:
6
附上错误代码:
#include<bits/stdc++.h>
using namespace std;
long long n,m,a[1000005],b[1000005],k,sum;
int d;
string r(int m,string a1,int b)
{
int lena;
int a[30],c[30],lenb,x=0,lenc=1;
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
lena=a1.size();
for (register int i=0;i<lena;i++)
a[i+1]=a1[i]-'0';
for (register int i=1;i<=lena;i++)
{
c[i]=(x*10+a[i])/b;
x=(x*10+a[i])%b;
}
while(c[lenc]==0 && lenc<lena)
lenc++;
string s="";
for (register int i=lenc;i<=lena;i++)
s+=c[i]+'0';
if(m==0)return s;
else
{
d=x;
return "";
}
}
string cf(string a1,int b)
{
long long a[40],c[105],lena,lenb,lenc,x;
string cj;
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
lena=a1.size();
for (register int i=0;i<lena;i++) a[lena-i]=a1[i]-'0';
for (register int i=1;i<=lena;i++)
{
c[i]+=a[i]*b;
c[i+1]+=c[i]/10;
c[i]%=10;
}
lenc=lena;
while(c[lenc+1]>0)c[lenc+2]+=c[lenc+1]/10,c[lenc+1]%=10,lenc++;
while (c[lenc]==0&&lenc>1)
lenc--;
for (register int i=lenc;i>=1;i--)
cj+=c[i]+'0';
return cj;
}
string f(int c)
{
string s="",s1="";
for(;c>0;c/=10)
s+=c%10+'0';
for(;c<s.size();c++)
s1+=s[s.size()-c-1];
return s1;
}
int main(){
scanf("%d",&n);
for(register int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(register int i=1;i<=n;i++)
{
k=i,sum=0;
while(b[k]==0)
{
k=a[k],sum++;
if(k==i)break;
}
while(b[k]==0)b[k]=sum,k=a[k];
}
string s="1";
for(register int i=1;i<=n;i++)
{
string a=s,c1="";
c1=f(b[i]);
string t="";
t=cf(s,b[i]);
r(1,a,b[i]);
while(d!=0)
{
a=c1;
c1=f(d);
b[i]=d;
r(1,a,b[i]);
}
s=r(0,t,b[i]);
}
int q=1000007;
r(1,s,q);
printf("%d",d);
return 0;
}