P5550 Chino的数列

很想模拟,但是数据太大啦(悲。然后我想着用\(map\)映射来做,想着模拟几轮发现周期,然后映射求解。但是不知道为什么写崩了。勉强贴贴,反正不是正解(

#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=80+10, INF=0x3f3f3f3f;
ll n,s,m,k;
ll a[N];
string S;
string To(ll x[N]){
	string y;
	for(re int i=1;i<=n;i++)y+=(x[i]+'0');
	return y;
}
map<string,bool> f;
map<int,string> f2;
int main(){
	int loop=0;
	cin>>n>>s>>m>>k;
	for(re int i=1;i<=n;i++)cin>>a[i];
	S=To(a);
	f[S]=0;
	f2[0]=S;
	while(f[S]){
		f[S]=1;
		loop++;
		swap(a[s],a[m]);
		int t=a[1];
		for(int i=1;i<n;i++)a[i]=a[i+1];
		a[n]=t;
		S=To(a);
		f2[loop]=S;
	}
	cout<<f2[k%loop]<<endl;
	return 0;
}

要造转移矩阵,悲,刚开始还造错了(yun
搞了一上午,终于好力(悲

#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=80+10, INF=0x3f3f3f3f;
ll n,s,m,k;
ll A[N][N];
ll A1[N][N],A2[N][N]; 
ll a[N][N];
ll ans[N][N]; 
void f1(){//a=A1*A2
	ll B[N][N]={0};
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			for(int k=1;k<=n;k++){
				B[i][j]=B[i][j]+A1[i][k]*A2[k][j];
			}
		}
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			a[i][j]=B[i][j];
}
void f2(){//ans*=a
	ll B[N][N]={0};
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			for(int k=1;k<=n;k++){
				B[i][j]=B[i][j]+a[i][k]*ans[k][j];
			}
		}
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			ans[i][j]=B[i][j];
}
void f3(){//a*=a
	ll B[N][N]={0};
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			for(int k=1;k<=n;k++){
				B[i][j]=B[i][j]+a[i][k]*a[k][j];
			}
		}
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			a[i][j]=B[i][j];
}
void f4(){//ans=A*ans
	ll B[N][N]={0};
	for(int i=1;i<=1;i++){
		for(int j=1;j<=n;j++){
			for(int k=1;k<=n;k++){
				B[i][j]=B[i][j]+A[i][k]*ans[k][j];
			}
		}
	}
	for(int i=1;i<=1;i++)
		for(int j=1;j<=n;j++)
			ans[i][j]=B[i][j];
}
int main(){
	cin>>n>>s>>m>>k;
	for(int i=1;i<=n;i++)cin>>A[1][i];
	for(int i=1;i<=n;i++){
		ans[i][i]=1;
		A1[i][i]=1;
	}
	A1[s][m]=1;A1[m][s]=1;A1[s][s]=0;A1[m][m]=0;
	for(int i=1;i<n;i++)A2[i+1][i]=1;
	A2[1][n]=1;
	f1();
	while(k>0){
		if(k&1)f2();
		f3();
		k>>=1;
	}
	f4();
	for(int i=1;i<=n;i++){
		cout<<ans[1][i]<<' ';
	}
	return 0;
}
posted @ 2023-07-11 23:01  LsmQwQ  阅读(23)  评论(0)    收藏  举报