题目连接:https://www.51nod.com/Challenge/Problem.html#problemId=1774
思路:每次都是1到r进行排序,所以每次后面大的r会覆盖前面较小的r,所以选择出最大的r,然后倒叙维护排序操作,排序也就是反转。具体可见代码理解。
#include
#include
using namespace std;
#define LL long long
int n, m;
int arr[200001];
int tmp[200001];
int ans[200001];
int t[200001];
int r[200001];
int main()
{
while(cin >> n >> m)
{
memset(tmp, 0, sizeof(tmp));
memset(ans, 0, sizeof(ans));
memset(t, 0, sizeof(t));
memset(r, 0, sizeof(r));
for(int i = 1 ; i <= n ; i ++)
{
scanf("%d", &arr[i]);
tmp[i] = arr[i];
ans[i] = arr[i];
}
int maxx = -1, x , y;
for(int i = 1 ; i <= m ; i ++)
{
scanf("%d %d", &x, &y);
t[y] = x;
r[y] = i; //后面的操作会覆盖前面的同一位置操作
maxx = max(maxx, y);
}
sort(tmp+1, tmp + 1 + maxx); //最大的r升序排列
for(int i = maxx ; i > 0 ; i --)
{
if(r[i] < r[i+1]) //后面的升降序操作覆盖前面的操作,只取r最大的
{
r[i] = r[i+1];
t[i] = t[i+1];
}
}
int l = 1, r = maxx;
for(int i = maxx ; i > 0 ; i --)
{
if(t[i] == 2) ans[i] = tmp[l++]; //降序则将前面的数值反转至后面
else ans[i] = tmp[r--]; //升序正常
}
for(int i = 1; i <= n ; i ++)
{
cout << ans[i];
if(i == n) cout << endl;
else cout << " ";
}
}
return 0;
}