ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列
题目描述
DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知
道N次操作后数列中所有元素的和。他还要玩其他游戏,所以这个问题留给你解决。

Input

第一行一个整数N,然后有N行,每行三个正整数a、b、k。
N<=40000 , a、b、k<=10^9

Output

一个数,数列中所有元素的和
一个位置最终的值是覆盖它的所有区间的k的最大值
离散化,堆维护最大值扫描一次可得答案
#include<cstdio>
#include<queue>
#include<algorithm>
struct heap{
    std::priority_queue<int>h,hd;
    inline void ins(int x){h.push(x);}
    inline void del(int x){hd.push(x);}
    inline int top(){
        while(!hd.empty()&&h.top()==hd.top())h.pop(),hd.pop();
        return h.top();
    }
}h;
struct event{
    int x,v,t;
}e[80010];
bool operator<(event a,event b){
    return a.x<b.x;
}
int n,p=0;
long long ans=0;
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        e[p].x=a;
        e[p].t=1;
        e[p+1].x=b;
        e[p].v=e[p+1].v=c;
        p+=2;
    }
    e[p++]=(event){0,0,1};
    e[p++]=(event){1000000001,0,0};
    std::sort(e,e+p);
    int px=0,mx=0;
    e[p].x=-1;
    for(int i=0,j;i<p;i=j){
        j=i;
        while(e[j].x==e[i].x)++j;
        for(int k=i;k<j;k++)if(e[k].t)h.ins(e[k].v);else h.del(e[k].v);
        ans+=1ll*mx*(e[i].x-px);
        px=e[i].x;
        mx=h.top();
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted on 2016-07-02 19:40  nul  阅读(510)  评论(0编辑  收藏  举报