概述
组下标从1开始的数组s,进行q次操作:考虑两种操作:
1 r,将子序列a[1] 到a[r] 从小到大排序
2 r,将子序列a[1] 到a[r] 从大到小排序
输入
第一行输入T组数据T (1 ≤ T ≤ 10)
第一行输入两个数字n, q(1 ≤ n, q ≤ 1e4)
第二行包含n个整数ai(−1e9 ≤ ai ≤ 1e9) —初始序列
然后q行表示m个操作. 第i行包含两个整数op(1 ≤ op ≤ 2), r(1 ≤ r ≤ n)
输出
输出n个数字,即数组被操作q次改变后的数组
注意,我们要输出的是最终改变后的结果
输入样例
2
3 1
1 2 3
2 2
4 2
1 2 4 3
2 3
1 2
输出样例
2 1 3
2 4 1 3
HINT
在第二组样例中初始序列是: 1 2 4 3.
执行第一次操作后的序列是: 4 2 1 3. 执行第二次操作后的序列是: 2 4 1 3.
分析题意可得,这组序列的最终结果一定是r值最大的那一个以及在它后面的那些比它小的r值导致的,这样就有了思路
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int maxn = 1e5 + 20;
int re[maxn];//用来储存r值最大的那一部分在初始时的数组
int ans[maxn];//用来储存最终答案数组
int in[maxn];//初始输入数组
int s2[maxn], s[maxn];//分别记录r和op
int main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
memset(re, 0, sizeof(re));
memset(in, 0, sizeof(in));
memset(s2, 0, sizeof(s2));
memset(s, 0, sizeof(s));
int n, m;
cin >> n >> m;
for (int i = 1; i <=n; i++) scanf("%d", &in[i]);
int tt = 1;
s2[0] = 1e6;
for (int i = 0; i < m; i++)//如果你输入的r值比前面的r值大的话,tt指针后退找到比你当前r值大的r值,然后从它开始重新输入
{
int a1, a2;
scanf("%d%d", &a1, &a2);
while (a2 >=s2[tt - 1]) tt--;
s2[tt] = a2, s[tt] = a1, tt++;
}
for (int i = s2[1]+1; i <= n; i++) ans[i] = in[i];//因为r值后的数组不受影响所以直接读入就好
for (int i = 1; i <= s2[1]; i++)
re[i] = in[i];
sort(re + 1, re + 1 + s2[1]);//先排序;
int uu = 1, kk = s2[1];
for (int i = 1; i <= m; i++)
{
if (s[i] == 1)//如果当前顺序要求是升序,那么按着re数组的顺序读入就好,一直读到下一个顺序,所以是从后面往前输入
{
for (int j = s[i]; j >s[i + 1]; j--) ans[j] = re[kk--];
}
else
{
for (int j = s[i]; j > s[i + 1]; j--)
ans[j] = re[uu++];
}
}
for (int i = 1; i < n; i++) printf("%d ", ans[i]);
printf("%dn", ans[n]);
}
system("pause");
return 0;
}
最后
以上就是欢喜自行车为你收集整理的暑假第二场积分赛————F题的全部内容,希望文章能够帮你解决暑假第二场积分赛————F题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复