蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列
题目描述
DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知
道N次操作后数列中所有元素的和。他还要玩其他游戏,所以这个问题留给你解决。
标签:set space 元素 output put har include arp insert
题解:当一段区间先进行操作l,r,a,再进行操作l,r,b时,最后的结果一定是a,b中的最大值,那我们直接离线处理。对于每段区间,直接让它变成所有包含这段区间的操作中的最大值。用multiset维护一下就好了
#include <cstdio> #include <cstring> #include <iostream> #include <set> #include <algorithm> using namespace std; typedef long long ll; const int maxn=40010; int n,tot; ll ans; multiset<ll> s; struct node { int org,k; ll v,val; }p[maxn<<1]; bool cmp(node a,node b) { return a.v<b.v; } int main() { scanf("%d",&n); int i,j; for(i=1;i<=n;i++) { scanf("%lld%lld%lld",&p[tot+1].v,&p[tot+2].v,&p[tot+1].val); if(p[tot+1].v==p[tot+2].v) continue; p[tot+2].val=p[tot+1].val,p[tot+2].k=1,tot+=2; } sort(p+1,p+tot+1,cmp); multiset<ll>::iterator it; for(i=1;i<=tot;i++) { if(p[i].v!=p[i-1].v&&!s.empty()) { it=s.end(),--it; ans+=(p[i].v-p[i-1].v)*(*it); } if(p[i].k) it=s.find(p[i].val),s.erase(it); else s.insert(p[i].val); } printf("%lld",ans); return 0; }
标签:set space 元素 output put har include arp insert
原文地址:http://www.cnblogs.com/CQzhangyu/p/6801545.html