【bzoj4636】蒟蒻的数列

来源:互联网 发布:ipone卡通贴图软件 编辑:程序博客网 时间:2024/06/03 06:53

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 40005typedef 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 (!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;}