AtCoder AGC031D A Sequence of Permutations (群论、置换快速幂)

题目链接

https://atcoder.jp/contests/agc031/tasks/agc031_d

题解

这居然真的是个找规律神题。。。

首先要明白置换的一些基本定义,置换\(p\)和\(q\)的复合\(a\)定义为\(a_i=p_{q_i}\), 记作\(a=pq\). 有定理\((pq)^{-1}=q^{-1}p^{-1}\).
显然题目里定义的\(f(p,q)=qp^{-1}\).
然后打表打出前几项:
\(a_1=p\)
\(a_2=q\)
\(a_3=qp^{-1}\)
\(a_4=qp^{-1}q^{-1}\)
\(a_5=qp^{-1}q^{-1}pq^{-1}\)
\(a_6=qp^{-1}q^{-1}p^2q^{-1}\)
\(a_7=qp^{-1}q^{-1}pqpq^{-1}\)
\(a_8=qp^{-1}q^{-1}pqp^{-1}qpq^{-1}\)
好像……规律并不明显啊……
好吧,结论是\(a_n=ga_{n-6}g^{-1}\), 其中\(g=qp^{-1}q^{-1}p\). (这是怎么看出来的……)
知道了结论,我们还是比较容易归纳证明的: 显然\(gg^{-1}=e\) (\(e\)为单位元,\(e_i=i\)), 于是\(a_n=(ga_{n-7}g^{-1})(ga_{n-8}g^{-1})^(-1)=ga_{n-7}a_{n-8}^{-1}g^{-1}=ga_{n-6}g^{-1}\).
于是设\(m'=\lfloor \frac{m-1}{6}\rfloor, n'=m-6m'\), \(a_n=g^{m'}n'g^{-m'}\), 直接快速幂计算即可,时间复杂度\(O(n\log m)\)或\(O(n)\).

代码

#include<cstdio>
#include<cstdlib>
#include<cassert>
#include<iostream>
using namespace std;

inline int read()
{
    int x=0; bool f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
    for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
    if(f) return x;
    return -x;
}

const int N = 1e5;
const int lgM = 30;
int p[N+3],q[N+3],pp[N+3],qq[N+3];
int g[N+3],f[N+3],ff[N+3];
int tmp[N+3];
int aux[N+3];
int ans[N+3];
int a[7][N+3];
int n,m;

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) scanf("%d",&p[i]),pp[p[i]] = i;
    for(int i=1; i<=n; i++) scanf("%d",&q[i]),qq[q[i]] = i;
    for(int i=1; i<=n; i++) a[1][i] = p[i],a[2][i] = q[i];
    for(int k=3; k<=6; k++)
    {
        for(int i=1; i<=n; i++) a[k][a[k-2][i]] = a[k-1][i];
    }
    for(int 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(int i=0; m; i++)
    {
        if(m&(1<<i))
        {
            m-=(1<<i);
            for(int j=1; j<=n; j++) aux[j] = f[tmp[j]];
            for(int j=1; j<=n; j++) f[j] = aux[j];
        }
        for(int j=1; j<=n; j++) aux[j] = tmp[tmp[j]];
        for(int j=1; j<=n; j++) tmp[j] = aux[j];
    }
    for(int i=1; i<=n; i++) ff[f[i]] = i;
    for(int i=1; i<=n; i++) ans[i] = f[a[nn][ff[i]]];
    for(int i=1; i<=n; i++) printf("%d ",ans[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/suncongbo/p/11517907.html

时间: 2024-10-14 17:14:29

AtCoder AGC031D A Sequence of Permutations (群论、置换快速幂)的相关文章

HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 249    Accepted Submission(s): 140 Problem Description Farmer John likes to play mathematics games with his N cows. Recently, t

POJ 2778 DNA Sequence (AC自动机 + 矩阵快速幂)

题目链接:DNA Sequence 解析:AC自动机 + 矩阵加速(快速幂). 这个时候AC自动机 的一种状态转移图的思路就很透彻了,AC自动机就是可以确定状态的转移. AC代码: #include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; const int MOD = 100000; struct Matrix{ int ma

HDU-6395多校7 Sequence(除法分块+矩阵快速幂)

Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1731    Accepted Submission(s): 656 Problem Description Let us define a sequence as below F1=A F2=B Fn=C⋅Fn−2+D⋅Fn−1+⌊Pn⌋ Your job is s

POJ 2778 DNA Sequence(AC自动机+矩阵快速幂)

题目链接:http://poj.org/problem?id=2778 题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 思路:Trie图的状态转移,用矩阵mat[i][j]来表示从结点i到j只走一步有几种走法,那么mat的n次幂就表示从结点i到j走n步有几种走法,题目要求解的就是从头节点走n步且不包含危险结点的走法. mat = mat^n   ans = (mat[0][0] + mat[0][1] + ...

POJ 2778 DNA Sequence —— (AC自动机+矩阵快速幂)

距离上次做AC自动机有很久了=.=,以前这题的思路死活看不懂,现在还是觉得很好理解的. 思路参见:http://blog.csdn.net/morgan_xww/article/details/7834801#. 我用cnt=1表示这个节点是危险的,然后再匹配fail指针的时候,如果一个节点的前缀是危险的,那么这个节点也是危险的,这么维护即可. 顺便一提,我以前的AC自动机模板是没有build过程中失配时的nxt指针的(以前是在match的过程中体现),但是失败时候需要的nxt指针又是很好用的,

【POJ】2778 DNA Sequence(AC自动机+矩阵快速幂)

题目 传送门:QWQ 分析 对着Trie图搞快速幂. 为什么这样是对的呢? 详见:http://www.matrix67.com/blog/archives/276 有些地方还不是很理解......为什么节点还要往下扩展? 有空再来搞一搞 代码 1 //#include <bits/stdc++.h> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespa

【HDOJ5950】Recursive sequence(矩阵乘法,快速幂)

题意:f[1]=a,f[2]=b,f[i]=2f[i-2]+f[i-1]+i^4(i>=3),多组询问求f[n]对2147493647取模 N,a,b < 2^31 思路:重点在于i^4的处理 对于i转移矩阵中可以记录下它的0,1,2,3,4次项 i的幂又可以由i-1的幂运算得出,最后推出的系数是二项式展开的系数 试试新的矩乘模板 1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #inc

POJ 2778 DNA Sequence ( Trie图、矩阵快速幂 )

题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析: 我们先分析Tire 图的结构 : Trie图是在AC自动机的原型上增添边使得状态可以快速转移,标记危险的节点(后缀是不良单词的节点): 那我们是想构造长度是n不包含不良串对不对 , 那是不是在trie图上从0节点走n步到安全节点的方案数(Trie图也是状态转移图) 在一个有向图中,A走k步到B的方案数(这显然是经典的矩阵快速幂问题),(原理需要自己搜索)先对原图建立一个邻接表M[i][j] , M

hdu 5667 Sequence 矩阵快速幂

题目链接:hdu 5667 Sequence 思路:因为fn均为a的幂,所以: 这样我们就可以利用快速幂来计算了 注意: 矩阵要定义为long long,不仅仅因为会爆,还会无限超时 要对a%p==0特判,以为可能出现指数%(p-1)==0的情况,那么在快速幂的时候返回的结果就是1而不是0了 /************************************************************** Problem:hdu 5667 User: youmi Language: