牛客国庆集训派对day1 J Princess Principal(RMQ或栈)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/oidoidoid/article/details/82943127

题目链接

题解1:统计每个括号匹配的位置,统计区间最小和区间最大,如果都在区间内说明是一个有效的序列。

题解2:直接用栈统计,通过记录每个括号进栈时栈的状态,来比较得出是否为有序的序列。

敲了个RMQ的板子

写的很好的BLOg

题解1代码(空间和时间其实有点极限)

#include<iostream>
#include<stack>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#define go(i,a,b) for (int i=(a);i<=(b);i++)
#define N 1000010
#define logN 21
using namespace std;
int minn[N][logN],maxn[N][logN],a[N],p[N];

void work(int a[], int n){
	memset(minn,0x3f,sizeof(minn));
	memset(maxn,0,sizeof(maxn));
	for (int i=1;i<=n;i++){
		minn[i][0]=a[i];
		maxn[i][0]=a[i];
	}
	for (int j=1;(1<<j)<=n;j++){
		for (int i=1;i+(1<<j)-1<=n;i++){
			minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]);
			maxn[i][j]=max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]);
		}
	}
}
int query(int l, int r, int c){
	if (l>r) swap(l,r);
 	if (l==r) return p[l];
	int len=(r-l+1);
	int k=int(log10((double)len)/log10(2.0));
	if (!c) return min(minn[l][k],minn[r-(1<<k)+1][k]);
	else return max(maxn[l][k],maxn[r-(1<<k)+1][k]);
}

stack<int>stk;
int main(){
	int n,m,q;
	scanf("%d%d%d",&n,&m,&q);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if (stk.empty()||a[i]%2==0||a[i]%2==1&&a[stk.top()]!=a[i]-1) stk.push(i);
		else{
			p[stk.top()]=i;
			p[i]=stk.top();
			stk.pop();
		}
	}
	while (!stk.empty()){
		if (a[stk.top()]%2) p[stk.top()]=n+1;
		else p[stk.top()]=0;
		stk.pop();
	}
	/*
	for (int i=1;i<=n;i++) printf("%d ",p[i]);
	cout<<endl;
	*/
	work(p,n);
	int l,r;
	while (q--){
		scanf("%d%d",&l,&r);
		if (query(l,r,0)>=l&&query(l,r,1)<=r) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

题解2(比较正解)

#include<iostream>
#include<stack>
#define N 1000050 
using namespace std;
int a[N],p[N];
stack<int> stk;
int main(){
	int n,m,q;
	scanf("%d%d%d",&n,&m,&q);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if (stk.empty()) stk.push(i);
		else if (a[stk.top()]==(a[i]^1)&&a[stk.top()]+1==a[i]) stk.pop();
		else stk.push(i);
		if (!stk.empty()) p[i]=stk.top();
	}
	int l,r;
	while (q--){
		scanf("%d%d",&l,&r);
		if (p[r]==p[l-1]) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/oidoidoid/article/details/82943127