題目鏈接:【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
*/