bzoj2653(可持久化線段樹)

 

新姿勢

注意區間的合併問題,比如最大前綴和最大後綴的合併,表示被這裏卡了好長時間

 

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<utility>
#define fi first
#define se second
#define MK(a,b) make_pair((a),(b))
#define pii pair<int,int>
using namespace std;
const int N=20005;

int n,m;
int val[N],to[N],rt[N];
pii b[N];


int tot;
struct aa
{
	int l,r,lc,rc,sum,qz,hz;
	int len(){return r-l+1;}
}a[N*30];


void up(int u)
{
	int l=a[u].lc,r=a[u].rc;
	a[u].sum=a[l].sum+a[r].sum;
	a[u].qz=max(a[l].sum+a[r].qz,a[l].qz);
	a[u].hz=max(a[r].sum+a[l].hz,a[r].hz);
}
void build(int &u,int l,int r)
{
	u=++tot;
	a[u].l=l,a[u].r=r;
	if (l==r) 
	{
		a[u].sum=a[u].qz=a[u].hz=1;
		return ;
	}
	int mid=(l+r)>>1;
	build(a[u].lc,l,mid);
	build(a[u].rc,mid+1,r);
	up(u);
}
void insert(int old,int &now,int pos)
{
	now=++tot;a[now]=a[old];
	if (a[old].l==a[old].r)
	{
		a[now].sum=-1;
		a[now].qz=a[now].hz=0;
		return ;
	}
	int mid=(a[old].l+a[old].r)>>1;
	if (pos<=mid) insert(a[old].lc,a[now].lc,pos);
	else insert(a[old].rc,a[now].rc,pos);
	up(now);
}
void init()
{
	sort(b,b+n);	
	build(rt[0],0,n-1);
	for (int i=1;i<n;i++) insert(rt[i-1],rt[i],b[i-1].se);
}
int find_sum(int u,int l,int r)
{
	if (a[u].l==l&&a[u].r==r) return a[u].sum;
	int mid=(a[u].l+a[u].r)>>1;
	if (r<=mid) return find_sum(a[u].lc,l,r);
	if (mid<l) return find_sum(a[u].rc,l,r);
	return find_sum(a[u].lc,l,mid)+find_sum(a[u].rc,mid+1,r); 
}
int find_qz(int u,int l,int r)
{
	if (l>r) return 0;
	if (a[u].l==l&&a[u].r==r) return a[u].qz;
	int mid=(a[u].l+a[u].r)>>1;
	if (r<=mid) return find_qz(a[u].lc,l,r);
	if (mid<l) return find_qz(a[u].rc,l,r);
	return max(find_sum(a[u].lc,l,mid)+find_qz(a[u].rc,mid+1,r),find_qz(a[u].lc,l,mid));
}
int find_hz(int u,int l,int r)
{
	if (l>r) return 0;
	if (a[u].l==l&&a[u].r==r) return a[u].hz;
	int mid=(a[u].l+a[u].r)>>1;
	if (r<=mid) return find_hz(a[u].lc,l,r);
	if (mid<l) return find_hz(a[u].rc,l,r);
	return max(find_sum(a[u].rc,mid+1,r)+find_hz(a[u].lc,l,mid),find_hz(a[u].rc,mid+1,r));
}
int pan(int mid,int *q)
{
	return find_sum(rt[mid],q[1],q[2])+find_hz(rt[mid],q[0],q[1]-1)+find_qz(rt[mid],q[2]+1,q[3]);
}
void work(int *q,int &x)
{
	int l=0,r=n-1,ans=0,mid;
	while (l<=r)
	{
		mid=(l+r)>>1;
		if (pan(mid,q)>=0) ans=mid,l=mid+1;
		else r=mid-1;
	}
	printf("%d\n",b[ans].fi);x=b[ans].fi;
}
int main()
{
	scanf("%d",&n);
	for (int i=0;i<n;i++) scanf("%d",&val[i]),b[i]=MK(val[i],i);
	
	init();
	
	int x=0,q[4];
	scanf("%d",&m);
	while (m--)
	{
		scanf("%d%d%d%d",&q[0],&q[1],&q[2],&q[3]);
		for (int i=0;i<4;i++) q[i]=(q[i]+x)%n;
		sort(q,q+4);
		work(q,x);
	}
	return 0;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章