【BZOJ4636】蒟蒻的数列 STL

【BZOJ4636】蒟蒻的数列

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

题解:当一段区间先进行操作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;
}
原文地址:https://www.cnblogs.com/CQzhangyu/p/6801545.html