# [BZOJ 2653] middle

## 题意

$$n\le 2\times 10^4,q\le2.5\times 10^4$$.

## 题解

### 参考代码

#include <bits/stdc++.h>

const int MAXN=20010;

struct Node{
struct Data{
int sum;
int lsum;
int rsum;
Data(){}
Data(int a,int b,int c):sum(a),lsum(b),rsum(c){}
Data friend operator+(const Data& a,const Data& b){
return Data(
a.sum+b.sum,
std::max(a.lsum,a.sum+b.lsum),
std::max(b.rsum,a.rsum+b.sum)
);
}
};
int l;
int r;
Data v;
Node* lch;
Node* rch;
Node(Node*);
void Print();
Node(int,int);
void Negate(int);
Data Query(int,int);
};
Node* N[MAXN];

int n;
int q;
int cnt;
int a[MAXN];
int s[MAXN];
std::vector<int> pos[MAXN];

int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",a+i);
s[i]=a[i];
}
std::sort(s+1,s+n+1);
cnt=std::unique(s+1,s+n+1)-(s+1);
for(int i=0;i<n;i++){
a[i]=std::lower_bound(s+1,s+cnt+1,a[i])-s;
pos[a[i]].push_back(i);
}
N[1]=new Node(0,n-1);
for(int i=1;i<cnt;i++){
N[i+1]=new Node(N[i]);
for(auto p:pos[i])
N[i+1]->Negate(p);
}
scanf("%d",&q);
int lastans=0;
for(int i=0;i<q;i++){
int q[4];
for(int i=0;i<4;i++){
scanf("%d",q+i);
(q[i]+=lastans)%=n;
}
std::sort(q,q+4);
int l=1,r=cnt+1;
while(r-l>1){
int mid=(l+r)>>1;
int sum=0;
if(q[2]-q[1]>1)
sum+=N[mid]->Query(q[1]+1,q[2]-1).sum;
sum+=N[mid]->Query(q[0],q[1]).rsum+N[mid]->Query(q[2],q[3]).lsum;
if(sum>=0)
l=mid;
else
r=mid;
}
printf("%d\n",lastans=s[l]);
}
return 0;
}

Node::Node(Node* p){
*this=*p;
}

Node::Data Node::Query(int l,int r){
if(l<=this->l&&this->r<=r)
return this->v;
else{
if(r<=this->lch->r)
return this->lch->Query(l,r);
if(this->rch->l<=l)
return this->rch->Query(l,r);
return this->lch->Query(l,r)+this->rch->Query(l,r);
}
}

void Node::Negate(int x){
if(this->l==this->r)
this->v=Data(-1,-1,-1);
else{
if(x<=this->lch->r){
this->lch=new Node(this->lch);
this->lch->Negate(x);
}
else{
this->rch=new Node(this->rch);
this->rch->Negate(x);
}
this->v=this->lch->v+this->rch->v;
}
}

void Node::Print(){
if(this==NULL)
return;
printf("[%d,%d] {sum=%d,lsum=%d,rsum=%d}\n",l,r,v.sum,v.lsum,v.rsum);
this->lch->Print();
this->rch->Print();
}

Node::Node(int l,int r):l(l),r(r){
if(l==r)
this->v=Data(1,1,1);
else{
int mid=(l+r)>>1;
this->lch=new Node(l,mid);
this->rch=new Node(mid+1,r);
this->v=this->lch->v+this->rch->v;
}
}


posted @ 2019-02-24 20:14  rvalue  阅读(136)  评论(0编辑  收藏  举报