线段树套线段树求救
查看原帖
线段树套线段树求救
278259
RemiliaScar1et楼主2021/4/21 15:58

大红大紫

线段树套线段树,用了标记永久化

#include <bits/stdc++.h>
using namespace std;

const int N=5e4+10,M=N*17*17,INF=1e8;

int intersec(int a,int b,int c,int d)
{
	return min(b,d)-max(a,c)+1;
}

int n,m;
struct Node1
{
	int lson,rson,sum,tag;
} tree[M];
int idx=0;

#define lnode tree[node].lson
#define rnode tree[node].rson

void update(int node,int start,int end,int l,int r)//区间+1
{
	tree[node].sum+=intersec(l,r,start,end);
	if(l<=start && end<=r)
	{
		tree[node].tag++;
		return ;
	}
	int mid=(start+end)>>1;
	if(l<=mid) 
	{
		if(!lnode) lnode=++idx;
		update(lnode,start,mid,l,r);
	}
	if(r>mid)
	{
		if(!rnode) rnode=++idx;
		update(rnode,mid+1,end,l,r);
	}
}

int Query(int node,int start,int end,int l,int r,int add)//区间求和(标记永久化)
{
	if(l<=start&&end<=r) return tree[node].sum+(end-start+1)*add;
	int mid=(start+end)>>1;
	add+=tree[node].tag;
	int res=0;
	if(l<=mid) 
	{
		if(lnode) res+=Query(lnode,start,mid,l,r,add);
		else res+=intersec(start,mid,l,r);
	}
	if(r>mid)
	{
		if(rnode) res+=Query(rnode,mid+1,end,l,r,add);
		else res+=intersec(mid+1,end,l,r);
	}
	return res;
}

struct Node2
{
	int l,r,root;
} tr[N];

#undef lnode
#undef rnode
#define lnode node<<1
#define rnode node<<1|1

void build(int node,int l,int r)
{
	tr[node].l=l,tr[node].r=r,tr[node].root=++idx;
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(lnode,l,mid);
	build(rnode,mid+1,r);
}

void modify(int node,int l,int r,int c)
{
	update(tr[node].root,1,n,l,r);
	if(tr[node].l==tr[node].r) return ;
	int mid=(tr[node].l+tr[node].r)>>1;
	if(c<=mid) modify(lnode,l,r,c);
	else modify(rnode,l,r,c);
}

int query(int node,int l,int r,int c)
{
	if(tr[node].l==tr[node].r) return tr[node].r;
	int mid=tr[node].l+tr[node].r>>1;
	int k=Query(tr[rnode].root,1,n,l,r,0);
	if(k>=c) return query(rnode,l,r,c);
	return query(lnode,l,r,c);
}

struct Que
{
	int opt,a,b,c;
} q[N];

vector<int> disc;

int find(int x)
{
	return lower_bound(disc.begin(),disc.end(),x)-disc.begin();
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d%d",&q[i].opt,&q[i].a,&q[i].b,&q[i].c);
		if(q[i].opt==1) disc.push_back(q[i].c);
	}
	sort(disc.begin(),disc.end());
	disc.erase(unique(disc.begin(),disc.end()),disc.end());
	build(1,0,disc.size()-1);
	
	for(int i=1;i<=m;i++)
	{
		int opt=q[i].opt, l=q[i].a,r=q[i].b, c=q[i].c;
		if(opt==1) modify(1,l,r,find(c));
		else printf("%d\n",disc[query(1,l,r,c)]);
	}
	return 0;
}
2021/4/21 15:58
加载中...