【线段树+离散化】Uestc-数据结构专题训练【B】

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#define inf 0x3f3f3f3f
#define LL unsigned long long
#define left_child now<<1,l,mid
#define right_child now<<1|1,mid+1,r
using namespace std;
int n,q;
struct node{
	int l,r;
	long long tot;
	bool lazy;
}e[100010*4];
int map[100010*3],map2[100010*3],Hashhash[100010*3];
int k=1;
int a,b,c,m;
int op[100010];
int Left[100010];
int Right[100010]; 
int f(int u)
{
	int now=0;
		now = lower_bound(map + 1,map + 1 + m,u) - map;
	return now;
}
void build(int now,int l,int r)
{
	e[now].l=l,e[now].r=r;
	if(l==r)return;
	int mid=(l+r)>>1;
	build(left_child);
	build(right_child);
}
void pushdown(int k)  
{  
    e[k<<1].tot = map[e[k<<1].r]-map[e[k<<1].l-1];
    e[k<<1].lazy=1;
    e[k<<1|1].tot = map[e[k<<1|1].r]-map[e[k<<1|1].l-1];
	e[k<<1|1].lazy=1; 
	e[k].lazy=0;
}  
void update(int now,int l,int r,int x,int y)
{
	if(map[x-1]+1<=map[l-1]+1&&map[r]<=map[y])
//	if(x<=l&&r<=y)
	{
		e[now].tot=map[r]-map[l-1];
		e[now].lazy=1;
		return ;
	}
//	if(e[now].lazy==1)pushdown(now);
if(e[now].lazy==1)return ;
	int mid=(l+r)>>1;
	if(y<=mid)
	{
		update(now<<1,l,mid,x,y);
	}
	else if(x>mid)
	{
		update(now<<1|1,mid+1,r,x,y);
	}
	else
	{
		update(now<<1,l,mid,x,y);
		update(now<<1|1,mid+1,r,x,y);
	}
	e[now].tot=e[now<<1].tot+e[now<<1|1].tot;
}
int query(int now,int l,int r,int x,int y)
{
	if(map[x-1]+1<=map[l-1]+1&&map[r]<=map[y])
//	if(x<=l&&r<=y)
	{
		return e[now].tot;
	}
	int mid=(l+r)>>1;
if(e[now].lazy==1)return min(map[r],map[y])-max(map[l-1]+1,map[x-1]+1)+1;
//	if(e[now].lazy==1)pushdown(now);
	if(y<=mid)return query(now<<1,l,mid,x,y);
	else if(x>mid)return query(now<<1|1,mid+1,r,x,y);
	else
	{
		return query(now<<1,l,mid,x,mid)+query(now<<1|1,mid+1,r,mid+1,y);
	}
}
int main()
{
	scanf("%d%d",&n,&q);
	for(int i=1;i<=q;i++)
	{
		scanf("%d%d%d",&a,&b,&c);
		op[i]=a;
		Left[i]=b;
		Right[i]=c;
		map[k++]=b-1;
		map[k++]=c;
	}
	for(int i=1;i<=2*q;i++)map2[i]=map[i];
	sort(map+1,map+k);
	m= unique(map+1,map+k)-map-1;//去重后有M个 
	for(int i = 1;i <= m;++i)Hashhash[i] = i;
	build(1,1,m);
	map[0]=0;
	for(int i=1;i<=q;i++)
	{	
		if(op[i]==1)
		{
			update(1,1,m,f(Left[i]),f(Right[i]));
		//	update(1,1,m,Left[i],Right[i]);
		}
		else
		{
			printf("%d\n",Right[i]-Left[i]+1-query(1,1,m,f(Left[i]),f(Right[i])));
		  //  printf("%d\n",Right[i]-Left[i]+1-query(1,1,m,Left[i],Right[i]));
		}
	}
	return 0;
}

自己的代码。

另贴一大神的代码。

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<vector>
using namespace std;
int n,q;
struct Q
{
	int op,l,r;
}ques[100000+10];
vector<int>stable;
int m;
struct T
{
	int l,r;
	int sum;
	bool flag;//这道题的特殊性质,可以不用标准的lazy处理方法 
}tree[100000*8+10];
void build(int id,int l,int r)
{
	tree[id].l=l;tree[id].r=r;tree[id].flag=0;
	if(l==r)return;
	int mid=l+r>>1;
	build(id<<1,l,mid);
	build(id<<1|1,mid+1,r);
}
void update(int id,int l,int r)
{
	if(l<=stable[tree[id].l-1]+1&&stable[tree[id].r]<=r)
	{
		tree[id].flag=true;tree[id].sum=stable[tree[id].r]-stable[tree[id].l-1];
		return;
	}
	if(tree[id].flag)return;
	int mid=tree[id].l+tree[id].r>>1;
	if(l<=stable[mid])update(id<<1,l,r);
	if(r>stable[mid])update(id<<1|1,l,r);
	tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;
}
int query(int id,int l,int r)
{
	if(l<=stable[tree[id].l-1]+1&&stable[tree[id].r]<=r)
	{
//		cerr<<stable[tree[id].l-1]+1<<" "<<stable[tree[id].r]<<endl;
		return tree[id].sum;
	}
	if(tree[id].flag)
	{
		return min(r,stable[tree[id].r])-max(l,stable[tree[id].l-1]+1)+1;
	}
	int ret=0;
	int mid=tree[id].l+tree[id].r>>1;
	if(l<=stable[mid])ret+=query(id<<1,l,r);
	if(r>stable[mid])ret+=query(id<<1|1,l,r);
	return ret;
}
int main()
{
	scanf("%d%d",&n,&q);
	for(int i=1;i<=q;i++)
	{
		scanf("%d%d%d",&ques[i].op,&ques[i].l,&ques[i].r);
		stable.push_back(ques[i].l-1);
		stable.push_back(ques[i].r);
	}
	//stable.push_back(0);
	sort(stable.begin(),stable.end());
	stable.erase(unique(stable.begin(),stable.end()),stable.end());
	m=stable.size()-1;
//	for(int i=1;i<=m;i++)printf("  %d",stable[i]);printf("\n");
	build(1,1,m);
	for(int i=1;i<=q;i++)
	{
		if(ques[i].op==1)update(1,ques[i].l,ques[i].r);
		else printf("%d\n",ques[i].r-ques[i].l+1-query(1,ques[i].l,ques[i].r));
	} 
	return 0;
}


你可能感兴趣的:(【线段树+离散化】Uestc-数据结构专题训练【B】)