# AT4694 题解

题目传送门 AT4694

我的原 blog

(LaTeX 不显示,凑活看吧。。。)

# 题意简述

给定两个排列,使其满足要求。

# 题目分析

这种题一般来说都会先上来枚举找一找规律,先列上八个找找看呀!

a1=pa_1=p

a2=qa_2=q

a_3=qp^

a_4=qp^{-1}q^

a_5=qp^{-1}q^{-1}pq^

a_6=qp^{-1}q^{-1}p^2q^

a_7=qp^{-1}q^{-1}pqpq^

a_8=qp^{-1}q^{-1}pqp^{-1}qpq^

列着列着,诶?怎么发现了什么?没错,规律出来了!计算通项就是 an=bab1a_n=ba_b^{-1}, 其中 b=qp1q1pb=qp^{-1}q^{-1}p

知道了结论,我们还是比较容易归纳证明的:显然 bb1=ebb^{-1}=e (ee 为单位元,ei=ie_i=i)。

于是设 n=m6mn'=m-6m', an=bmanbma_n=b^{m'}a_{n'}b^{-m'}

我们之后就可以开心的写快速幂的代码啦!

# 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include<bits/stdc++.h>
#define int long long
#define rint register int
using namespace std;

int p[1000005],q[1000005],pp[1000005],qq[1000006],g[1000005],f[1000005],ff[1000005],tmp[1000005],aux[1000005],cnt[1000005],a[10][1000005],n,m;
signed main(){
cin>>n>>m;

for(rint i=1;i<=n;i++)
{
cin>>p[i];
pp[p[i]] = i;
}

for(rint i=1;i<=n;i++)
{
cin>>q[i];
qq[q[i]] = i;
}

for(rint i=1;i<=n;i++)
{
a[1][i]=p[i];
a[2][i]=q[i];
}

for(rint k=3;k<=6;k++)
for(rint i=1;i<=n;i++)
a[k][a[k-2][i]]=a[k-1][i];

for(rint i=1;i<=n;i++)
{
g[i]=q[pp[qq[p[i]]]];
f[i]=i;
tmp[i]=g[i];
}

int nn=m%6==0?6:m%6;
m=(m-1)/6;

for(rint i=0;m!=0;i++)
{
if(m&(1<<i))
{
m-=(1<<i);
for(rint j=1;j<=n;j++)
aux[j]=f[tmp[j]];

for(rint j=1;j<=n;j++)
f[j]=aux[j];
}

for(rint j=1;j<=n;j++)
aux[j]=tmp[tmp[j]];

for(rint j=1;j<=n;j++)
tmp[j]=aux[j];
}

for(rint i=1;i<=n;i++)
ff[f[i]]=i;
for(rint i=1;i<=n;i++)
cnt[i]=f[a[nn][ff[i]]];
for(rint i=1;i<=n;i++)
cout<<cnt[i]<<" ";
puts("");
}
Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

spaceswalker WeChat Pay

WeChat Pay

spaceswalker Alipay

Alipay

spaceswalker PayPal

PayPal