CodeForces 631C Report(找規律)

題目鏈接:【CodeForces 631C】

長度是n的數列,m個次訪問,兩種操作:1、t=1,將數列1~r從小到大排序;2、t=2,將數列1~r從大到小排列。輸出最後得到的數列

如果i>j&&ri>rj,那麼i之前的操作都是無效的,所以我們可以根據這個刪選t、r,因此第一個r(記爲R)肯定是最大的

數組a存的是原數列

數組a[j](R<j<=n)這部分是不變的,變的只是1~R這一塊(用數組b記錄),那就從R開始往前推出最終的數組a

將數組b從小到大排序

仔細找找規律,想象一下我們可以發現這個規律:

訪問i時,如果i-1的t等於1,數組a的後幾位就是數組b的後幾位,否則數組a的後幾位就是數組b的前幾位

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[2*N], b[2*N], t[2*N], r[2*N];
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i=1; i<=n; i++) 
	{
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	int ti, ri, len=0;
	for(int i=0; i<m; i++)
	{
		scanf("%d%d", &ti, &ri);
		while(len && ri>=r[len-1]) len--;
		t[len]=ti, r[len]=ri, len++;
	}
	r[len++]=0;
	sort(b+1, b+1+r[0]);
	int lb=1, rb=r[0];
	for(int i=1; i<len; i++)
	{
		for(int j=r[i-1]; j>r[i]; j--)
		{
			if(t[i-1]==1) a[j]=b[rb--];
			else a[j]=b[lb++];
		} 
	}
	printf("%d", a[1]);
	for(int i=2; i<=n; i++)
	{
		printf(" %d", a[i]);
	}
	printf("\n");
	return 0;
}
/*
10 5
2 4 3 6 9 7 10 8 1 5
2 9
2 8
1 6
2 4
1 2
*/


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