Codeforces 631C Report排序+思维

点击打开链接

//题意:n,k<=2e5 n个数,k个操作 输入t,ri 把1~ri排成非递增或非递减(t=0||1)

//容易看出 若i<j&&ri<rj 则操作i无效 因为最终会被操作j覆盖 

//所以最后剩下的操作为 i<j ri>rj

//r[i]为递减,r[i]操作后a的r[i+1]+1~r[i]这段不会在改变 

为了找到r[i+1]~r[i]这段将b从小到大排序 
t=1 递增时 a中r[i+1]+1~r[i]为b的后几位

t=0 递减时 a中的r[i+1]+1~r[i]为b的前几位

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll mod=1e8+7;
const int N=2e5+20;
int a[N],b[N],t[N];
//题意:n,k<=2e5 n个数,k个操作 输入t,ri 把1~ri排成非递增或非递减(t=0||1)
//容易看出 若i<j&&ri<rj 则操作i无效 因为最终会被操作j覆盖 
//所以最后剩下的操作为 i<j ri>rj
int r[N]; 
int main()
{
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	int op=0;
	for(int i=1;i<=k;i++)
	{
		scanf("%d%d",&t[i],&r[i]);
		while(op>0&&r[i]>=r[op-1])
		op--;
		
		t[op]=t[i];
		r[op]=r[i];
		op++;
	}
	r[op]=0; 
	for(int i=1;i<=r[0];i++)// r[i]+1~n没有操作的 
	{
		b[i]=a[i];
	}
	sort(b+1,b+1+r[0]);
	//b从小到大 
	//t=1 递增时 a中r[i+1]+1~r[i]为b的后几位
	//t=0 递减时 a中的r[i+1]+1~r[i]为b的前几位
	//r[i]为递减,每次操作后a的r[i+1]+1~r[i]这段不会在改变 
	int st=1,ed=r[0];
	//时间复杂度为O(nlogn+op) 
	for(int i=0;i<op;i++)
	{
		for(int j=r[i];j>r[i+1];j--)
		{
			if(t[i]==1)
			{
				a[j]=b[ed--];	
			}	
			else
			{
				a[j]=b[st++];
			}
		}	
	}
	for(int i=1;i<=n;i++)
	{
		printf("%d",a[i]);
		if(i==n)
		cout<<endl;
		else
		cout<<' ';
	}
	return 0;	
} 
/* 
10 5 
2 4 3 6 9 7 10 8 1 5 
2 9 
2 8 
1 6 
2 4 
1 2 
*/  





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值