Codeforces Round 923 (Div. 3) D. Find the Different Ones!

70 阅读2分钟

D. Find the Different Ones!

这道题目很好理解,题目就是给你一个序列,q次询问,每次给出一个区间,让你求出这个区间是否存在不同的元素,若存在则输出其中任意的一对坐标,若不存在则输出“-1 -1”,根据给出的数据范围直接暴力枚举是不可行的,会在第二组数据就tle,所以就要另寻他路。

1.预处理输入

我的思路是在输入数组的时候对数组进行预处理,给每一个数组建一个结构体,分别存入当前元素id,以及在这个元素左边最近的不同元素的下标。 处理代码如下:

struct s
{
	int id,res;
}a[N];

以上是结构体,以下是输入预处理:

	for(int i = 1 ; i <= n ; i++)
	{
		cin>>a[i].id;
		if(a[i].id != a[i - 1].id)
		{
			a[i].res = i - 1;
		}else
		{
			a[i].res = a[i - 1].res;
		}
	}

2.如何处理询问

现在每一个数组都记录着自己的元素以及左边离自己最近的不同元素,接下来就可以思考如何处理q次询问了,每一次询问看似是给了你一个[l , r]的区间,但是我们并没有必要去遍历他,我们只需要检查其中的一个元素就可以判断组序列之间是否存在异元素,思考一下,对于其中一个元素而言无非两种情况:1.区间中存在与它不同的元素,此时锁定异元素下表并输出。2.区间内全是与它相同的元素,此时输出“-1 -1”即可。

3.从何处开始处理数组

这个就很简单就能想到了,因为步骤一的时候每一个结构体存的是左边最近异元素,所以我们就直接检查区间中最右边的元素,若它的res >= l,直接输出,不然说明整个区间全是与它相同的元素。

AC代码如下

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Os")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("Og")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair <ll , ll> pii;
typedef priority_queue <ll ,vector<ll> ,greater<ll> > xiao;  
typedef priority_queue <ll ,vector<ll> ,less<ll> > da; 
const int N=2e6 + 10,M = 0x3f3f3f3f;
const ull P = 131;

struct s
{
	int id,res;
}a[N];

void work()
{
	int n;
	cin>>n;

	for(int i = 1 ; i <= n ; i++)
	{
		cin>>a[i].id;
		if(a[i].id != a[i - 1].id)
		{
			a[i].res = i - 1;
		}else
		{
			a[i].res = a[i - 1].res;
		}
	}
	
	int q;
	cin>>q;
	
	while(q--)
	{
		int l,r;
		cin>>l>>r;
		if(a[r].res >= l)
		{
			cout<<r<<" "<<a[r].res<<"\n";
		}else
		{
			cout<<"-1 -1"<<"\n";
		}
	}
	cout<<"\n";
}

int main()
{
	std::ios::sync_with_stdio(false);
    std::cin.tie(0),cout.tie(0);

	int t;
	cin>>t;
	while(t--)
	{
		work();
	}
}