中石油訓練賽 - Swapity Swap(矩陣快速冪)

題目描述

Farmer John's N cows (1≤N≤100) are standing in a line. The ith cow from the left has label i, for each 1≤i≤N.
Farmer John has come up with a new morning exercise routine for the cows. He tells them to repeat the following two-step process exactly K (1≤K≤109) times:
1.The sequence of cows currently in positions A1…A2 from the left reverse their order (1≤A1<A2≤N).
2.Then, the sequence of cows currently in positions B1…B2 from the left reverse their order (1≤B1<B2≤N).
After the cows have repeated this process exactly K times, please output the label of the ith cow from the left for each 1≤i≤N.

輸入

The first line of input contains N and K. The second line contains A1 and A2, and the third contains B1 and B2.

輸出

On the ith line of output, print the label of the ith cow from the left at the end of the exercise routine.

樣例輸入

7 2
2 5
3 7

樣例輸出

1
2
4
3
5
7
6

提示

Initially, the order of the cows is [1,2,3,4,5,6,7] from left to right. After the first step of the process, the order is [1,5,4,3,2,6,7]. After the second step of the process, the order is [1,5,7,6,2,3,4]. Repeating both steps a second time yields the output of the sample.


題目大意:給出一個1~n的數列,初始時爲1,2,3...n-1,n,接下來進行 k 次操作,每次操作有兩個步驟:

  1. 將[ l , r ]內的數字翻轉
  2. 將[ ll , rr ]內的數字翻轉

問操作 k 次後的數列變成了什麼樣子

題目分析:因爲 k 高達1e9,所以暴力翻轉肯定是不行的,所以自然而然想到了快速冪,因爲 n 只有100,而且是對於數列進行的操作,所以不難想到矩陣快速冪,具體如下:

不難看出,只需要將單位矩陣按照特殊的區間限制稍微變換一下就好了,每次與初始矩陣相乘後,得到的結果都是相應區間轉換完成後的結果,而題目中要求的是每次翻轉兩個區間,兩個區間帶來的影響是會有重疊部分不好處理,但用矩陣來處理的話,只需要將兩個區間的轉移矩陣單獨預處理好後,然後相乘一下就好了

代碼:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
      
typedef long long LL;
     
typedef unsigned long long ull;
      
const int inf=0x3f3f3f3f;
 
const int N=100;

const int mat_size = 100;//矩陣大小,需要乘以2,爲了&運算的時候需要二倍的矩陣大小

struct Matrix
{
	unsigned long long a[mat_size][mat_size];
	int x, y;//長寬
	Matrix()	//返回0矩陣
	{
		memset(a,0,sizeof(a));
	}
	Matrix(int x,int y)//返回0矩陣,並且x,y賦值
	{
		this->x = x;
		this->y = y;
		memset(a, 0,sizeof(a));
	}
 
	Matrix(int n)	//返回n*n的【單位矩陣】
	{
		this->x=n;
		this->y=n;
		memset(a,0,sizeof(a));
		for (int i = 0; i <n;++i)	a[i][i]=1;
	}
	Matrix operator * (const Matrix &B)//矩陣乘法
	{
		Matrix tmp;
		for (int i = 0; i < x; ++ i)
			for (int j = 0; j < B.y; ++ j)
			{
				tmp.a[i][j] = 0;
				for (int k = 0; k < y; ++ k)
				{
					tmp.a[i][j] = (tmp.a[i][j] + a[i][k] * B.a[k][j]);
				}
			}
		tmp.x = x;
		tmp.y=B.y;
		return tmp;
	}
	Matrix operator ^ (int b)//矩陣A的b次方
	{
		Matrix ret = Matrix(x);  
		Matrix A = *this;
		while( b )  
		{  
			if( b & 1 )	ret = ret * A ;  
			b >>= 1 ;  
			A = A * A ;  
		}  
		return ret ;  
	}
	Matrix operator & (int b)//A^0 + A^1+A^2+A^3+++A^n,其中A是矩陣。最後返回的就是一個矩陣
	{
		Matrix ret = *this;
		for (int i = ret.x; i < ret.x * 2; ++ i)	
		{
			ret.a[i-ret.x][i]= 1;
			ret.a[i][i] = 1;
		}
		ret.x <<= 1;
		ret.y <<= 1;
		//pg(ret);
		ret = ret^b;
		ret.x >>= 1;
		ret.y >>= 1;
		for (int i = 0; i < ret.x; ++ i)	
			for (int j = 0; j < ret.y; ++ j)
				ret.a[i][j] += ret.a[i][j + ret.x];
		return ret;
	}
	void pg(Matrix A)
	{
		for (int i = 0; i <A.x; ++i)
		{
			for (int j = 0; j < A.y;++j)	cout<<A.a[i][j]<<" ";cout<<endl;
		}
		cout<<endl;
 
	}
};

int main()
{
#ifndef ONLINE_JUDGE
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
	int n,k;
	scanf("%d%d",&n,&k);
	int l,r,ll,rr;
	scanf("%d%d%d%d",&l,&r,&ll,&rr);
	l--,r--,ll--,rr--;
	Matrix a(n,n),b(n,n);
	for(int i=0;i<n;i++)
	{
		a.a[i][i]=1;
		b.a[i][i]=1;
	}
	for(int i=l;i<=r;i++)
		a.a[i][i]=0;
	for(int i=l;i<=r;i++)
		a.a[i][r-(i-l)]=1;
	for(int i=ll;i<=rr;i++)
		b.a[i][i]=0;
	for(int i=ll;i<=rr;i++)
		b.a[i][rr-(i-ll)]=1;
	Matrix temp=a*b;
	Matrix ans(n,n);
	for(int i=0;i<n;i++)
		ans.a[0][i]=i+1;
	ans=ans*(temp^k);
	for(int i=0;i<n;i++)
		printf("%d\n",ans.a[0][i]);
	
	
	
	
	
	
	
	
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章