中石油训练赛 - 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 2.Then, the sequence of cows currently in positions B1…B2 from the left reverse their order (1≤B1 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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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 >= 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 

 

你可能感兴趣的:(矩阵快速幂)