bzoj3110: [Zjoi2013]K大数查询

Posted f321dd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3110: [Zjoi2013]K大数查询相关的知识,希望对你有一定的参考价值。

喜闻乐见的简单树套树= =第一维按权值建树状数组,第二维按下标建动态开点线段树,修改相当于第二维区间加,查询在树状数组上二分,比一般的线段树还短= =可惜并不能跑过整体二分= =另外bzoj上的数据有负数= =额其他树套树方法也是可以的爱怎么套怎么套= =

#include<cstdio>
#define J (i+j>>1)
#define I (J+1)
typedef unsigned ll;
const int N=1e5+5;
ll n,m,q,i,j,k,l,s,t,v;
struct node{
	ll s,t;
	node *i,*j;
};
node f[N*320],*e[N];
node* back=f;
void vary(node*& k,int s,
int t,int i=1,int j=n){
	if(!k)k=back++;
	k->s+=t-s+1;
	if(s==i&&t==j)++k->t;
	else if(t<I)
		vary(k->i,s,t,i,J);
	else if(s>J)
		vary(k->j,s,t,I,j);
	else{
		vary(k->i,s,J,i,J);
		vary(k->j,I,t,I,j);
	}
}
void eval(node* k,int s,
int t,int i=1,int j=n){
	if(!k)return;
	if(s==i&&t==j){
		l+=k->s;return;
	}
	l+=k->t*(t-s+1);
	if(t<I)
		eval(k->i,s,t,i,J);
	else if(s>J)
		eval(k->j,s,t,I,j);
	else{
		eval(k->i,s,J,i,J);
		eval(k->j,I,t,I,j);
	}
}
int main(){
	struct{
		operator int(){
			int x;
			scanf("%d",&x);
			return x;
		}
	}it;
	n=it,m=n<<1^1,q=it;
	while(q--){
		j=it,s=it,t=it,k=it;
		if(j==2){
			for(i=65536,v=j=0;i;i>>=1)
				if(j+i<=m){
					l=0,eval(e[j+i],s,t);
					if(v+l<k)j+=i,v+=l;
				}
			printf("%d\n",n-j);
		}else
			for(i=n-k+1;i<=m;i+=i&-i)
				vary(e[i],s,t);
	}
}

  

以上是关于bzoj3110: [Zjoi2013]K大数查询的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3110[Zjoi2013]K大数查询 树套树

bzoj3110: [Zjoi2013]K大数查询

bzoj3110: [Zjoi2013]K大数查询

bzoj:3110: [Zjoi2013]K大数查询

Bzoj3110: [Zjoi2013]K大数查询

BZOJ 3110 [Zjoi2013]K大数查询