您的位置:首页 > 其它

【bzoj4636】蒟蒻的数列

2017-10-23 19:12 399 查看
Description

蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列

题目描述

DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知

道N次操作后数列中所有元素的和。他还要玩其他游戏,所以这个问题留给你解决。

Input

第一行一个整数N,然后有N行,每行三个正整数a、b、k。

N<=40000 , a、b、k<=10^9

Output

一个数,数列中所有元素的和

Sample Input

4

2 5 1

9 10 4

6 8 2

4 6 3

Sample Output

16

题解

线段树区间修改最大值+永久化标记

答案扫一遍树即可

代码

#include<bits/stdc++.h>
#define mod 1000000007
#define inf 1000000000
#define N 40005
typedef long long ll;
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,sz,rt,ls[N*40],rs[N*40],mx[N*40];
ll ans;
void update(int &k,int l,int r,int x,int y,int z)
{
if(!k) k=++sz;
if (l==x&&r==y){mx[k]=max(mx[k],z);return;}
int mid=(l+r)>>1;
if (y<=mid) update(ls[k],l,mid,x,y,z);
else if (x>mid) update(rs[k],mid+1,r,x,y,z);
else update(ls[k],l,mid,x,mid,z),update(rs[k],mid+1,r,mid+1,y,z);
}
void query(int k,int l,int r,int x)
{
if
4000
(!k) return;
int mid=(l+r)>>1;
mx[k]=max(mx[k],x);
if (!ls[k]) ans+=(ll)mx[k]*(mid-l+1);
if (!rs[k]) ans+=(ll)mx[k]*(r-mid);
query(ls[k],l,mid,mx[k]);query(rs[k],mid+1,r,mx[k]);
}
int main()
{
n=read();
while (n--)
{
int a=read(),b=read(),k=read();
if (a>=b) continue;
update(rt,1,inf,a,b-1,k);
}
query(rt,1,inf,0);
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: