C. Not Equal on a Segment(ST表查询)

有俩种方法

. \color{Red}Ⅰ.查询区间的最大最小值

, 1 若最大最小值相等且等于询问数字,输出-1

否则挑一个不等的下标输出

S T , 线 我用的是ST表,当然你也可以用线段树啥啥的

. 使 \color{Red}Ⅱ.使用链表跳跃查询

p r e 可以预处理一个pre数组

, 如果中间一段全部相等,我直接跳到下一个不等的下标去

写法也简洁

ST表版本

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,m;
int a[maxn][23],b[maxn][23],numa[maxn][23],numb[maxn][23];
void init()
{
	for(int j=1;j<=21;j++)
	for(int i=1;i+(1<<j)-1<=n;i++)
	{
		int w=i+( 1<<(j-1) );
		if( a[i][j-1] >= a[w][j-1] )
		{
			a[i][j]=a[i][j-1];
			numa[i][j]=numa[i][j-1];
		}
		else
		{
			a[i][j]=a[w][j-1];
			numa[i][j]=numa[w][j-1];
		}
		if( b[i][j-1] <= b[w][j-1] )
		{
			b[i][j]=b[i][j-1];
			numb[i][j]=numb[i][j-1];
		}
		else
		{
			b[i][j]=b[w][j-1];
			numb[i][j]=numb[w][j-1];
		}
	}
}
bool get_max(int l,int r,int cha)
{
	int k=log2(r-l+1);
	int w=r-(1<<k)+1,num=0,maxx=0;
	if( a[l][k]>=a[w][k] )	maxx=a[l][k],num=numa[l][k];
	else	maxx=a[w][k],num=numa[w][k];
	if( maxx==cha )	return false;
	printf("%d\n",num);
	return true;
}
bool get_min(int l,int r,int cha)
{
	int k=log2(r-l+1);
	int w=r-(1<<k)+1,num=0,minn=0;
	if( b[l][k]<=b[w][k] )	minn=b[l][k],num=numb[l][k];
	else	minn=b[w][k],num=numb[w][k];
	if( minn==cha )	return false;
	printf("%d\n",num);
	return true;
}
int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i][0]);	
		b[i][0]=a[i][0];
		numa[i][0]=numb[i][0]=i;
	}
	init();
	for(int i=1;i<=m;i++)
	{
		int l,r,w;
		scanf("%d%d%d",&l,&r,&w);
		if( get_max(l,r,w) )	continue;
		if( get_min(l,r,w) )	continue;
		printf("-1\n");
	}
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107668184