Codeforces631C【栈维护+瞎搞】

题意:
百度。
思路:
如果该查询的R比前面的所有都大,那么前面所有都失效。
那么我先预处理出这些有效的。
那最坏的情况不就是栈里面元素(R)很多
n,n-1,n-2,n-3,n-4而且都是相反排序的。。。 

总不能每次都那样循环一下,跟着他变吧。

所以找特性:

如果有序列132456

我的栈是

1 6
2 5
1 3
2 2
那么第一步从sort完:123456,那么这个a[6]=6肯定是确定了对吧。
继续看 2 5:我们能确定 a[5]=1,a[4]=2 对吧

继续看1 3 :我们能确定a[3]=5。

继续看2 2:我们能确定a[2]=3,a[1]=4.

最后输出。这样我觉得仔细自己想想就能瞎搞出来了!自己想出来的方法才有乐趣啊~

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=2e5+10;
struct asd{
	int flag;
	int R;
}e[N];
stack<asd>q;
int a[N],b[N][2];
int tp[N];
bool cmp(int x,int y)
{
	return x>y;
}
int main()
{
	asd now,nex;
	int n,t;
	scanf("%d%d",&n,&t);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=t;i++)
		scanf("%d%d",&e[i].flag,&e[i].R);
	for(int i=1;i<=t;i++)
	{
		while(!q.empty()&&q.top().R<e[i].R)
			q.pop();
		if(!q.empty()&&e[i].flag==q.top().flag)
			continue;
		q.push(e[i]);
	}
	int num=0;
	while(!q.empty())
	{
		num++;
		b[num][0]=q.top().flag;b[num][1]=q.top().R;
		q.pop();
	}
	if(b[num][0]==1)
		sort(a+1,a+b[num][1]+1);
	else
		sort(a+1,a+b[num][1]+1,cmp);
	if(num==1)
	{
		for(int i=1;i<=n;i++)
			printf("%d ",a[i]);
		return 0;
	}
	int ii=n,jj=1,ij=n;
	int s=1;
	for(;ij>b[num][1];ij--,ii--)
		tp[ij]=a[ij];
	for(int i=num;i>=2;i--)
	{
		int cnt=b[i][1]-b[i-1][1];
		if(s%2==0)
			for(int p=1;p<=cnt;p++,ij--,jj++)
				tp[ij]=a[jj];
		else
			for(int p=1;p<=cnt;p++,ij--,ii--)
				tp[ij]=a[ii];
		s++;
	}
	if(s%2==0)
		for(int p=1;p<=b[1][1];p++,ij--,jj++)
			tp[ij]=a[jj];
	else
		for(int p=1;p<=b[1][1];p++,ij--,ii--)
				tp[ij]=a[ii];
	for(int i=1;i<=n;i++)
		printf("%d ",tp[i]);
	return 0;
}
/*
6 4
1 3 4 5 2 6
1 6
2 5
1 3
2 2
*/



原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777409.html