Atcoder 题面传送门 & 洛谷题面传送门

猜结论神题。

首先考虑探究题目中 \(f\) 函数的性质,\(f(p,q)_{p_i}=q_i\leftarrow f(p,q)\circ p=q\),其中 \(\circ\) 为两个置换的复合,\(a\circ b\) 为满足 \(p_{i}=a_{b_i}\) 的置换 \(p\),有点类似于函数的复合,u1s1 我一直把它当作乘法运算,因此总没搞清楚,心态爆炸……等式两边同乘 \(p\) 的复合逆 \(p^{-1}\) 可得 \(f(p,q)=q\circ p^{-1}\)。顺带一提复合满足性质 \((p\circ q)^{-1}=q^{-1}\circ p^{-1}\),这个对后面打表找规律有很大作用。

接下来考虑探究置换序列 \(a\) 的性质,我们不妨根据刚刚的性质先写出 \(a\) 的前几项看看瞧:

\[a_1=p
\]
\[a_2=q
\]
\[a_3=q\circ p^{-1}
\]
\[a_4=q\circ p^{-1}\circ q^{-1}
\]
\[a_5=q\circ p^{-1}\circ q^{-1}\circ p\circ q^{-1}
\]
\[a_6=q\circ p^{-1}\circ q^{-1}\circ p\circ p\circ q^{-1}
\]
\[\cdots
\]

注意到这东西是一个类似于线性递推的东西,并且此题 \(k\) 高达 \(10^9\),因此暴力推下去肯定是不行的,不过注意到相邻两项的 \(p,q\) 之间存在一些联系,具体来说,下一项实际上是对上一项进行如下变换:

  • 将所有 \(p\) 用 \(q\) 代替,\(p^{-1}\) 用 \(q^{-1}\) 代替
  • 将所有 \(q\) 用 \(q\circ p^{-1}\) 代替,\(q^{-1}\) 用 \(p\circ q^{-1}\) 代替

那有人就问了,知道这个性质有什么用呢?你就算做了这样一个转化,还不照样还是要递推吗?

这里又有一个考验眼力的地方,注意到 \(a_5\) 中出现了一个式子叫做 \(q\circ p^{-1}\circ q^{-1}\circ p\),我们不妨对其做一遍上面的变换,可得 \((q\circ p^{-1})\circ q^{-1}\circ (p\circ q^{-1})\circ q\),削消一下发现它就是 \(q\circ p^{-1}\circ q^{-1}\circ p\),也就是说从 \(a_5\) 开始出现的 \(q\circ p^{-1}\circ q^{-1}\circ p\) 在变换前后不会发生变化,记 \(A=q\circ p^{-1}\circ q^{-1}\circ p\),继续往下写几项可得:

\[a_5=A\circ q^{-1}
\]
\[a_6=A\circ p\circ q^{-1}
\]
\[a_7=A\circ q\circ p\circ q^{-1}
\]
\[a_8=A\circ q\circ p^{-1}\circ q\circ p\circ q^{-1}
\]

发现了什么?\(p^{-1}\circ q\circ p\circ q^{-1}\) 就是 \(A^{-1}\),因此 \(a_8\) 就等于 \(A\circ q\circ A^{-1}\),按照上面的方式 \(a_7\) 也可变形为 \(A\circ p\circ A^{-1}\)。

\(A,A^{-1}\) 在变换前后都可看作不动点,因此 \(a\) 序列可以看作类周期性变化的,即 \(a_n=A\circ a_{n-6}\circ A^{-1}\)

矩阵快速幂即可。

总之是一道考验眼力的猜结论神题。

const int MAXN=1e5;
int n,k;
struct perm{
int a[MAXN+5];
perm(){for(int i=1;i<=n;i++) a[i]=i;}
perm operator *(const perm &rhs) const{
perm ret;
for(int i=1;i<=n;i++) ret.a[i]=a[rhs.a[i]];
return ret;
}
} p,q;
perm inv(perm x){
perm ret;
for(int i=1;i<=n;i++) ret.a[x.a[i]]=i;
return ret;
}
perm qpow(perm x,int e){
perm ret;
for(;e;e>>=1,x=x*x) if(e&1) ret=ret*x;
return ret;
}
int main(){
scanf("%d%d",&n,&k);k--;perm ans;
for(int i=1;i<=n;i++) scanf("%d",&p.a[i]);
for(int i=1;i<=n;i++) scanf("%d",&q.a[i]);
perm A=q*inv(p)*inv(q)*p;
if(k%6==0) ans=p;
if(k%6==1) ans=q;
if(k%6==2) ans=q*inv(p);
if(k%6==3) ans=A*inv(p);
if(k%6==4) ans=A*inv(q);
if(k%6==5) ans=A*p*inv(q);
ans=qpow(A,k/6)*ans*qpow(inv(A),k/6);
for(int i=1;i<=n;i++) printf("%d ",ans.a[i]);
return 0;
}

最新文章

  1. 『.NET Core CLI工具文档』(八)dotnet-restore
  2. java并发编程学习: ThreadLocal使用及原理
  3. 去除表单自动填充时,-webkit浏览器默认给文本框加的黄色背景
  4. CSS控制文字,超出部分显示省略号
  5. iphone绘图的几个基本概念CGPoint、CGSize、CGRect、CGRectMake、window(窗口)、视图(view)
  6. SQL Server 造成cpu 使用率高的 6 原因
  7. PyCharm 2017 官网 下载 安装 设置 配置 (主题 字体 字号) 使用 入门 教程
  8. HDU 2196树形DP(2个方向)
  9. Linux基础操作命令
  10. Apache ab 压力并发测试工具
  11. Salesforce中的单点登录简介
  12. webform之Repeater控件
  13. linux中jdk的安装与配置
  14. ubuntu 中安装 ZED SDK 及结合ROS 的使用
  15. 分表需要解决的问题 &amp; 基于MyBatis 的轻量分表落地方案
  16. bzoj3065
  17. CIDR 无类别域间路由
  18. Strusts2笔记6--拦截器
  19. oracle中的术语
  20. [SDOI2010]地精部落 DP

热门文章

  1. noj加1乘2平方
  2. 【UE4 C++ 基础知识】&lt;11&gt;资源的同步加载与异步加载
  3. 【UE4 设计模式】组件模式 Components Pattern
  4. (数据科学学习手札129)geopandas 0.10版本重要新特性一览
  5. Azure File Storage(一)为本地机器配置网络磁盘
  6. 零基础要怎么样学习嵌入式Linux--走进嵌入式
  7. 用python检查矩阵的计算
  8. Python pylint requires Python '>=3.4.*' but the running Python is 2.7.12
  9. nod_1009 数字1的数量(分析题)
  10. poj 3417 Network (LCA,路径上有值)