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