线段树二分板子

//[1,x]内, 找一个最大的位置p, 使得[p,x]的和>=v
void find(int o, int l, int r) {
	if (p!=-1) return;
	if (r<=x) {
		if (l==r) { 
			if (s[o]>=v) p = l;
			else v -= s[o];
			return;
		}
		pd(o,l,r);
		if (s[rc]>=v) return find(rs);
		v -= s[rc];
		return find(ls);
	}
	pd(o,l,r);
	if (mid>=x) return find(ls);
	find(rs),find(ls);
}

//[x,n]内, 找一个最小的位置p, 使得[x,p]的和>=v
void find(int o, int l, int r) {
	if (p!=-1) return;
	if (x<=l) {
		if (l==r) {
			if (s[o]>=v) p = l;
			else v -= s[o];
			return;
		}
		pd(o,l,r);
		if (s[lc]>=v) return find(ls);
		v -= s[lc];
		return find(rs);
	}
	pd(o,l,r);
	if (mid<x) return find(rs);
	find(ls),find(rs);
}


//[1,x]内, 找一个最小的位置p, 使得[p,x]的和<=v
void find(int o, int l, int r) {
	if (x==-1) return;
	if (r<=x) {
		if (l==r) {
			if (s[o]<=v) v -= s[o], p = l;
			else x = -1;
			return;
		}
		pd(o,l,r);
		if (s[rc]>=v) return find(rs);
		//这里不要忘记设置p的值
		p = mid+1, v -= s[rc];
		return find(ls);
	}
	pd(o,l,r);
	if (mid>=x) return find(ls);
	find(rs),find(ls);
}


//[x,n]内, 找一个最大的位置p, 使得[x,p]的和<=v
void find(int o, int l, int r) {
	if (x==-1) return;
	if (x<=l) {
		if (l==r) {
			if (s[o]<=v) v -= s[o], p = l;
			else x = -1;
			return;
		}
		pd(o,l,r);
		if (s[lc]>=v) return find(ls);
		p = mid, v -= s[lc];
		return find(rs);
	}
	pd(o,l,r);
	if (mid<x) return find(rs);
	find(ls),find(rs);
}


//[1,x]内, 找一个最大的位置p, 使得[p,x]的最小值<=v
void find(int o, int l, int r) {
	if (p!=-1) return;
	if (r<=x) {
		if (l==r) {
			if (mi[o]<=v) p = l;
			return;
		}
		pd(o,l,r);
		if (mi[rc]<=v) return find(rs);
		return find(ls);
	}
	pd(o,l,r);
	if (mid>=x) return find(ls);
	find(rs),find(ls);
}


//[x,n]内, 找一个最小的位置p, 使得[x,p]的最小值<=v
void find(int o, int l, int r) {
	if (p!=-1) return;
	if (x<=l) {
		if (l==r) {
			if (mi[o]<=v) p = l;
			return;
		}
		pd(o,l,r);
		if (mi[lc]<=v) return find(ls);
		return find(rs);
	}
	pd(o,l,r);
	if (mid<x) return find(rs);
	find(ls),find(rs);
}

//[1,x]内, 找一个最小的位置p, 使得[p,x]的最小值>=v
void find(int o, int l, int r) {
	if (x==-1) return;
	if (r<=x) {
		if (l==r) {
			if (mi[o]>=v) p = l;
			else x = -1;
			return;
		}
		pd(o,l,r);
		if (mi[rc]<v) return find(rs);
		p = mid+1;
		return find(ls);
	}
	pd(o,l,r);
	if (mid>=x) return find(ls);
	find(rs),find(ls);
}

//[x,n]内, 找一个最大的位置p, 使得[x,p]的最小值>=v
void find(int o, int l, int r) {
	if (x==-1) return;
	if (x<=l) {
		if (l==r) {
			if (mi[o]>=v) p = l;
			else x = -1;
			return;
		}
		pd(o,l,r);
		if (mi[lc]<v) return find(ls);
		p = mid;
		return find(rs);
	}
	pd(o,l,r);
	if (mid<x) return find(rs);
	find(ls),find(rs);
}

 

posted @ 2019-05-18 00:15  uid001  阅读(187)  评论(0编辑  收藏  举报