zoukankan      html  css  js  c++  java
  • agc031D

    题目大意

    题解

    一道找规律的题目手玩了一天晚上直接打表切了我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;
    }
    
  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/gmh77/p/13675166.html
Copyright © 2011-2022 走看看