POJ 3368

借助这道题,顺便学习了离散化的思想。

写代码是一件需要专注的事情,离散化处理的时候精神不做到高度集中,一道水题不能快速切出,训练需要注意

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <deque>
using namespace std;

const int maxn= 1e5+5;

int a[maxn], b[maxn], L[maxn], R[maxn], hs[maxn];
int mm[maxn], sptb[maxn][20];

void InitRMQ(int n, int b[])
{
	mm[0]= -1;
	for (int i= 1; i<= n; ++i){
		mm[i]= i & (i-1) ? mm[i-1] : mm[i-1]+1;
		sptb[i][0]= b[i];
	}
	for (int j= 1; j<= mm[n]; ++j){
		for (int i= 1; i+(1<<j)-1<= n; ++i){
			sptb[i][j]= max(sptb[i][j-1], sptb[i+(1<<(j-1))][j-1]);
		}
	}
}
inline int AuxQuery(int x, int y)
{
	int k= mm[y-x+1];
	return max(sptb[x][k], sptb[y-(1<<k)+1][k]);
}
int Query(int l, int r)
{
	int id_l= hs[l], id_r= hs[r];
	if (id_l== id_r){
		return r-l+1;
	}
	int t= max(R[l]-l+1, r-L[r]+1);
	if (1< id_r-id_l){
		t= max(t, AuxQuery(id_l+1, id_r-1));
	}
	return t;
}

int main(int argc, char const *argv[])
{
	int n, q;
	while (~scanf("%d", &n) && n){
		scanf("%d", &q);
		for (int i= 1; i<= n; ++i){
			scanf("%d", a+i);
		}
		int tot= 1, th= 1;
		for (int i= 1; i<= n; ++i){
			if (i> 1 && a[i]!= a[i-1]){
				for (int j= th; j< i; ++j){
					L[j]= th;
					R[j]= i-1;
				}
				b[tot]= i-th;
				th= i;
				++tot;
			}
			hs[i]= tot;
		}
		for (int j= th; j<= n; ++j){
			L[j]= th;
			R[j]= n;
		}
		b[tot]= n+1-th;
		InitRMQ(tot, b);

		while (q--){
			int l, r;
			scanf("%d %d", &l, &r);
			printf("%d\n", Query(l, r));
		}
	}
	return 0;
}
posted @ 2021-05-13 21:56  IdiotNe  阅读(35)  评论(0编辑  收藏  举报