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]);
}