题目大意
题解
一道找规律的题目手玩了一天晚上直接打表切了我tmsb
一个显然的思路:把an用ab的某种运算表示出来,然后找规律
那么这个运算显然要满足结合律,题目给的运算并不符合
直接用置换群的概念,这样运算满足结合律,原来的(f(p,q)=p^{-1}q)
由于置换的乘法要考虑左右,因此(c=ab),(c^{-1}=b^{-1}a^{-1})
把an用ab及其逆元表示,发现每6个分组后有规律
a
b
Ab
BAb
BaBAb
BaaBAb
BabaBAb
BabAbaBAb
BabAAbaBAb
BabABAbaBAb
BabABaBAbaBAb
BabABaaBAbaBAb
BabABabaBAbaBAb
BabABabAbaBAbaBAb
BabABabAAbaBAbaBAb
BabABabABAbaBAbaBAb
BabABabABaBAbaBAbaBAb
BabABabABaaBAbaBAbaBAb
(AB是ab的逆元)
前后都是4个一组的加上几个剩下的,快速幂解决
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define ll long long
//#define file
using namespace std;
struct type{
int a[100001];
} a,b,A,B,c,I;
int n,m,i,j,k,l;
type turn(type a,type b)
{
static type c;
int i;
fo(i,1,n) c.a[i]=b.a[a.a[i]];
return c;
}
type ny(type a)
{
static type c;
int i;
fo(i,1,n) c.a[a.a[i]]=i;
return c;
}
type qpower(type a,int b)
{
static type ans;
ans=I;
while (b)
{
if (b&1) ans=turn(ans,a);
a=turn(a,a),b>>=1;
}
return ans;
}
type js1(int t)
{
type ans=qpower(turn(turn(turn(B,a),b),A),t/4);
if (t%4>=1) ans=turn(ans,B);
if (t%4>=2) ans=turn(ans,a);
if (t%4>=3) ans=turn(ans,b);
return ans;
}
type js2(int t)
{
type ans=I;;
if (t%4>=3) ans=turn(ans,B);
if (t%4>=2) ans=turn(ans,A);
if (t%4>=1) ans=turn(ans,b);
return turn(ans,qpower(turn(turn(turn(a,B),A),b),t/4));
}
int main()
{
#ifdef file
freopen("agc031d.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
fo(i,1,n) scanf("%d",&a.a[i]),I.a[i]=i;
fo(i,1,n) scanf("%d",&b.a[i]);
if (m<=6)
{
fo(i,1,m-1)
{
A=ny(a);
c=turn(A,b);
a=b,b=c;
}
fo(i,1,n) printf("%d ",a.a[i]);
}
else
{
A=ny(a),B=ny(b),l=(m-1)/6;
switch (m%6)
{
case 1:{j=l*4-1;k=l*4;break;}
case 2:{j=l*4;k=l*4+1;break;}
case 3:{j=l*4;k=l*4+2;break;}
case 4:{j=l*4+1;k=l*4+2;break;}
case 5:{j=l*4+2;k=l*4+3;break;}
case 0:{j=l*4+2;k=l*4+4;break;}
}
c=turn(js1(j),js2(k));
fo(i,1,n) printf("%d ",c.a[i]);
}
printf("
");
fclose(stdin);
fclose(stdout);
return 0;
}