1. 程式人生 > 實用技巧 >agc031D - A Sequence of Permutations

agc031D - A Sequence of Permutations

題目大意

題解

一道找規律的題目手玩了一天晚上直接打表切了我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("\n");
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}