摘要:
话说看Discuss看了半天,茫茫然不知所云,硬着头皮自己写了个线段树,居然过了。。。
#include <iostream>
#include <stdio.h>
using namespace std;
typedef struct Node{
int left;
int right;
int left_value;
int right_value;
int value;
int left_num;
int right_num;
int num;
Node *left_child;
Node *right_child;
void Construct(int, int);
void Insert(int, int, int);
int Calculate(int, int);
}Node;
const int size = 100000;
Node sTree[size*3];
Node *root = &sTree[0];
int len = 1;
int input[size+1] = {0};
void Node::Construct(int l, int r)
{
left = l;
right = r;
left_value = right_value = value = 0;
left_num = right_num = num = 0;
if( l == r ){
left_child = right_child = NULL;
return;
}
left_child = &sTree[len++];
right_child = &sTree[len++];
int mid = (left + right) >> 1;
left_child->Construct(l, mid);
right_child->Construct(mid+1, r);
}
void Node::Insert(int l, int r, int v)
{
if( l==left ){
left_num = r - l + 1;
left_value = v;
}
if( r==right){
right_num = r - l + 1;
right_value = v;
}
if( num < (r - l + 1) ){
num = r - l + 1;
value = v;
}
if(left==l && right==r){
return;
}
int mid = (left + right) >> 1;
if( l > mid ){
right_child->Insert(l, r, v);
return;
}
if( r <= mid){
left_child->Insert(l, r, v);
return;
}
left_child->Insert(l, mid, v);
right_child->Insert(mid+1, r, v);
}
int Node::Calculate(int l, int r)
{
//cout << "calculate:" << left << "," << right << "/t" << l << "," << r << endl;
if( left==l && right==r){
return num;
}
if( num == right-left+1 ){
return r - l + 1;
}
int mid = (left + right) >> 1;
if( l > mid ){
return right_child->Calculate(l, r);
}
if( r <= mid){
return left_child->Calculate(l, r);
}
int rt1, rt2, rt3;
rt1 = rt2 = rt3 = 0;
rt1 = left_child->Calculate(l, mid);
rt2 = right_child->Calculate(mid+1, r);
if(left_child->right_value == right_child->left_value){
rt3 = min(left_child->right_num, mid-l+1) + min(right_child->left_num, r-mid);
}
rt1 = max(rt1, rt2);
rt1 = max(rt1, rt3);
return rt1;
}
int main()
{
while(true){
int n, q;
scanf("%d", &n);
if(n == 0){
break;
}
scanf("%d", &q);
len = 1;
root->Construct(1, n);
int i=1;
for(int j=1; j<=n; j++){
scanf("%d", &input[j]);
if(input[j] != input[i]){
root->Insert(i, j-1, input[i]);
i=j;
}
}
root->Insert(i, n, input[i]);
for(int j=1; j<=q; j++){
int left, right;
scanf("%d%d", &left, &right);
printf("%d/n", root->Calculate(left, right));
}
}
return 0;
}