记录编号 84788 评测结果 AAAAAAAAAA
题目名称 [CEOI 1998]洗牌机 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.011 s
提交时间 2013-12-19 21:21:15 内存使用 0.28 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<iomanip>
using namespace std;
const int SIZEN=1001;
int N,S;
class REPLACE{
public:
	int a[SIZEN];
	void output(void){
		for(int i=1;i<=N;i++) cout<<a[i]<<" ";cout<<endl;
	}
	REPLACE(){//初始化为单位置换
		int i;
		for(i=1;i<=N;i++) a[i]=i;
	}
	void inverse(void);
};
void REPLACE::inverse(void){
	int at[SIZEN]={0};
	int i;
	for(i=1;i<=N;i++) at[i]=a[i];
	for(i=1;i<=N;i++) a[at[i]]=i;
}
int* getcyc(REPLACE &x){//将x表示为循环形式(确保为单循环)
	int *ans=new int[SIZEN];
	int i,k,tot=1;
	bool flag[SIZEN]={0};
	for(i=1;i<=N;i++){
		if(!flag[i]){
			k=i;
			do{
				flag[k]=true;
				ans[tot++]=k;
				k=x.a[k];
			}while(k!=i);
		}
	}
	return ans;
}
int modN(int x){
	return ((x%N)+N)%N;
}
REPLACE* pow(REPLACE &x,int n){//将置换x作n次方,返回'新置换'这一对象的位置
	REPLACE *ans_key=new REPLACE;
	REPLACE &ans=(*ans_key);
	int *cyc=getcyc(x);
	int atp[SIZEN]={0,1};
	int i=1,j=1,now=1,next;
	//x的循环每次向后走1个,atp每次向后走k个
	do{
		atp[j]=cyc[i];
		i--;i=modN(i-1)+1;
		j-=n;j=modN(j-1)+1;
	}while(i!=1);
	for(i=1;i<N;i++) ans.a[atp[i]]=atp[i+1];
	ans.a[atp[N]]=atp[1];
	return ans_key;
}
REPLACE P;
int quickpow(int a,int n){//a^n mod N
	int ans=1;
	while(n){
		if(n&1) ans=(ans*a)%N;
		a=(a*a)%N;
		n>>=1;
	}
	return (ans+N)%N;
}
bool init(void){
	if(scanf("%d%d",&N,&S)==EOF) return false;
	for(int i=1;i<=N;i++) scanf("%d",&P.a[i]);
	return true;
}
void work(void){
	int *s=getcyc(P);
	REPLACE &ans=(*pow(P,quickpow(2,S)));
	for(int i=1;i<=N;i++) printf("%d\n",ans.a[i]);
}
int main(){
	freopen("shuffle.in","r",stdin);
	freopen("shuffle.out","w",stdout);
	init();
	work();
	return 0;
}