agc031D - A Sequence of Permutations
阿新 • • 發佈:2020-09-15
題目大意
題解
一道找規律的題目手玩了一天晚上直接打表切了我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; }