P2061 [USACO07OPEN]City Horizon S(线段树+离散化)

有一个数列,初始值均为0,他进行N次操作,每次将数列[ai,bi)这个区间中所有比Hi小的数改为Hi,他想知道N次操作后数列中所有元素的和。

//每次把比Hi小的数改成Hi
//把所有询问按Hi从小到大排序
//暴力修改即可 
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
long long c[maxn<<2];
int lz[maxn<<2];
long long len[maxn<<2];
int t[maxn];
int m;
int b[maxn];
void build (int i,int l,int r) {
	if (l==r) {
		len[i]=b[l];
		return;
	}
	int mid=(l+r)>>1;
	build(i<<1,l,mid);
	build(i<<1|1,mid+1,r);
	len[i]=len[i<<1]+len[i<<1|1];
}
void pushdown (int i) {
	if (lz[i]) {
		c[i<<1]=1ll*len[i<<1]*lz[i];lz[i<<1]=lz[i];
		c[i<<1|1]=1ll*len[i<<1|1]*lz[i];lz[i<<1|1]=lz[i];
		lz[i]=0;
	}
}
void up (int i,int l,int r,int L,int R,int v) {
	if (l>=L&&r<=R) {
		c[i]=1ll*len[i]*v;lz[i]=v;
		return;
	}
	pushdown(i);
	int mid=(l+r)>>1;
	if (L<=mid) up(i<<1,l,mid,L,R,v);
	if (R>mid) up(i<<1|1,mid+1,r,L,R,v);
	c[i]=c[i<<1]+c[i<<1|1];
}
struct qnode {
	int l,r,h;
	bool operator < (const qnode &r) const {
		return h<r.h;	
	}
}q[maxn];
int p[maxn];
int main () {
	int tot=0;
	scanf("%d",&m);
	for (int i=1;i<=m;i++) {
		scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h);
		t[++tot]=q[i].l;
		q[i].r--;
		t[++tot]=q[i].r;
	}
	sort(t+1,t+tot+1);
	int mm=unique(t+1,t+tot+1)-t-1;
	int cnt=0;
	for (int i=1;i<=mm;i++) {
		b[++cnt]=1;
		p[i]=cnt;
		if (i<mm&&t[i+1]-t[i]>1) b[++cnt]=t[i+1]-t[i]-1;
	}
	//for (int i=1;i<=cnt;i++) printf("%d ",b[i]);
	//puts("");
	build(1,1,cnt);
	sort(q+1,q+m+1);
	for (int i=1;i<=m;i++) {
		int l=upper_bound(t+1,t+mm+1,q[i].l)-t-1;
		int r=upper_bound(t+1,t+mm+1,q[i].r)-t-1;
		//printf("%d %d\n",p[l],p[r]);
		up(1,1,cnt,p[l],p[r],q[i].h);
	}
	printf("%lld\n",c[1]);
}
posted @ 2021-07-21 16:21  zlc0405  阅读(49)  评论(0编辑  收藏  举报