题意
定义f(p,q)=r,(p,q,r都是排列)满足
r
p
i
=
q
i
r_{p_i}=q_i
rpi=qi
然后给出
a
1
,
a
2
a_1,a_2
a1,a2,且
a
n
+
2
=
f
(
a
n
,
a
n
+
1
)
a_{n+2}=f(a_n,a_{n+1})
an+2=f(an,an+1)
求
a
k
a_k
ak
n<=1e5,k<=1e9
题解
我们定义两个排列的乘法为
p*q=r,当
r
i
=
p
q
i
r_i=p_{q_i}
ri=pqi
那么显然,这个乘法不满足交换律
但是聪明的读者一定发现了这个乘法是满足结合律的
(具体怎么证?你可以表示出来(ab)c,再表示出来a(bc)来证)
这个乘法的单位元就是id,也即
A
i
=
i
A_i=i
Ai=i
(自然我们也就可以得到逆元的定义了:
A
A
i
−
1
=
i
A^{-1}_{A_i}=i
AAi−1=i)
此外呢还有一点,
(
p
q
)
−
1
=
q
−
1
p
−
1
(pq)^{-1}=q^{-1}p^{-1}
(pq)−1=q−1p−1(注意换了顺序)
不严谨证明见下:
我们令左边为A,则 A p q i = i A_{p_{q_i}}=i Apqi=i
令 B = q − 1 B=q^{-1} B=q−1,则 B q i = i B_{q_i}=i Bqi=i
令 C = p − 1 C=p^{-1} C=p−1,则 C p i = i C_{p_i}=i Cpi=i
令右边为D,则 D i = B C i D_i=B_{C_i} Di=BCi,那么我们令 i = p i i=p_i i=pi就有 D p i = B i D_{p_i}=B_i Dpi=Bi,那么类似地有 D p q i = i D_{p_{q_i}}=i Dpqi=i
那么A=D,证毕
然后题目所给的
f
(
p
,
q
)
f(p,q)
f(p,q),就
=
q
p
−
1
=qp^{-1}
=qp−1(证明可用类似上面的方法)
那么我们就可以愉快地打表了
Patience is important in this experiment.(官方题解说的)
em…然后我们可以把这个a写成
A
B
A
−
1
ABA^{-1}
ABA−1的形式(A、B是两个新的排列)
那么我们再打表打出A B
(注意我们如果把(A7,B7)写成
(
q
p
−
1
q
−
1
,
p
)
(qp^{-1}q^{-1},p)
(qp−1q−1,p)也是没问题的,但是这样我们就找不出来规律了)
嗯…
然后我们(根据规律)把A表示成
(
q
p
−
1
q
−
1
p
)
t
C
(
t
=
⌊
k
−
1
6
⌋
)
(qp^{-1}q^{-1}p)^tC (t=\lfloor\frac{k-1}{6}\rfloor)
(qp−1q−1p)tC(t=⌊6k−1⌋)
可以发现,C和B都是6为周期的
然后就快速幂计算那一坨,再打表搞出来B C即可算出A,然后即可算出
a
k
a_k
ak
综上,这是一道找规律神题…
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+6;//!
struct permutation{
int a[N];
permutation(){memset(a,0,sizeof a);}
int& operator [](int x){return a[x];}
}p,q,ip,iq,A,B,ans;
int n,k;
permutation operator *(permutation a,permutation b){
permutation c;
for(int i=1;i<=n;i++)
c[i]=a[b[i]];
return c;
}
permutation inv(permutation a){
permutation b;
for(int i=1;i<=n;i++)
b[a[i]]=i;
return b;
}
permutation operator ^(permutation a,int b){
permutation c;
for(int i=1;i<=n;i++)
c[i]=i;
while(b){
if(b&1)
c=c*a;
a=a*a;
b>>=1;
}
return c;
}
void Print(permutation x){
for(int i=1;i<=n;i++)
printf("%d ",x.a[i]);
puts("");
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&p[i]);
for(int i=1;i<=n;i++)
scanf("%d",&q[i]);
ip=inv(p);
iq=inv(q);
int f=(k-1)/6,g=k-f*6;
permutation h=q*ip*iq*p;
A=h^f;
if(g==1){
B=p;
}
else if(g==2){
B=q;
}
else if(g==3){
B=q*ip;
}
else if(g==4){
A=A*q;
B=ip;
}
else if(g==5){
A=A*q*ip;
B=iq;
}
else{
A=A*q*ip;
B=iq*p;
}
ans=A*B*inv(A);
Print(ans);
}