bzoj4415 [Shoi2013] Licensing line segment tree

Equivalent to find the k-th number in the interval, and support deleting points at the same time

The line segment tree operation of this question is a bit similar to noiD1T1. So it was adjusted for a long time.

Pay attention to the modulus of size, pay attention to the special judgment when looking for the kth interval


code:

#include<iostream>
#include<cstdio>
using namespace std;
#define zuo o<<1,l,mid
#define you o<<1|1,mid+1,r
#define N 700005
int sz[N<<4],n,o,a,b,c,zz,op,i;
bool ky;
void up(int o)
{
	int ll=o<<1,rr=o<<1|1;
	sz[o]=sz[ll]+sz[rr];
}
void jian(int o,int l,int r)
{
	if(l==r)
	{
		sz[o]=1;
   return ;
	}
	int mid=(l+r)>>1;
	jian(zuo);
	jian(you);	
	up(o);	
}
void gai(int o,int l,int r)
{	int mid=(l+r)>>1;
		if(a<=l&&b>=r)
		{
		if(op==0)sz[o]=0;		
		if(op==1) c+=sz[o];
		return ;
		}
	if(a<=mid)gai(zuo);
	if(b>mid)gai(you);
	up(o);
}
void cha(int o,int l,int r)
{
int mid=(l+r)>>1;
	if(a<=l&&r<=b)
	{
if(sz[o]<c){c-=sz[o];return ;}
if(l==r){c=l,ky=1;return;}
  if(sz[o<<1]<c)
  {  	c-=sz[o<<1];
  	cha(you);	
  }else
  {
cha(zuo);	 
  }	
  return ;	
	}	
   	if(a<=mid)cha(zuo);
   	if(b>mid&&ky==0)cha(you);
}
int main()
{
	scanf("%d",&n);
	jian(1,1,n);
	zz=1;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&o);
      o%=sz[1];
		if(i==n){printf("%d",zz);return 0;}
o++;
		//找位置
		op=1;a=zz;b=n;c=0;gai(1,1,n);
		if(c<o)
		{o-=c;
		a=1;b=zz;
		}else
		{	a=zz;b=n;
		}
		ky=0;c=o;cha(1,1,n);
		//输出
		printf("%d\n",c);
		zz=c;
		op=0;a=b=c;gai(1,1,n);		
		//换位置 
		op=1;a=zz;b=n;c=0; gai(1,1,n);
			
			if(c==0)
			{
	a=1;b=n;	
			}else
			{
	a=zz;b=n;
			 }ky=0;			 
	c=1;cha(1,1,n);zz=c;		
	}
}


Guess you like

Origin blog.csdn.net/haobang866/article/details/79249157