SSL_1220【促销】

促销

题目

Bytelandish连锁超市委托你编写一个程序来模拟一项即将施行的促销活动,该活动的规则如下:
●想要参与的顾客,只需把他的个人资料写在帐单上,并把帐单放入投票箱;
●每天活动结束时,数额最大、最小的两张帐单被取出,付款数额最大的顾客将获得一笔奖金,价值为取出的两张帐单的数额之差;
●为了不重复计算,取出的两张帐单不再放回箱子,而剩下的帐单仍保留在箱中,进行第二天的活动。
超市每天的营业额很大,因此可假定:每天活动结束时,箱中至少有两张帐单以供取出。
你的任务是根据每天投入箱中的帐单,计算出这项促销活动期间超市付出的奖金总数额。

Input

第一行是整数n(1≤n≤5000),表示促销活动持续的天数。以下n行,每行是一些用空格分开的非负整数。第i+1行上的数字表示第i天投入箱中的帐单的数额,该行第一个整数k(0≤k≤105)代表这天的帐单总数目,接下来的k个正整数表示每张帐单的数额,不超过106
整个活动期间,投入箱中的帐单不超过106张。

Output

含一个整数,即整个活动中的奖金总额。

Sample Input

5
3 1 2 3
2 1 1
4 10 5 5 1
0
1 2

Sample Output

19

解析

发现最多只有106个帐单,考虑用带log算法水过去,事实证明这是可行的
贪心策略:
建立一个大根堆,一个小根堆和一个map<int,bool>
每出现一个帐单,就同时扔进三个容器,然后从两个堆顶取出已经用过的帐单,再计算两个堆之差,将两个堆顶弹出并在map中删除即可,这就是著名的懒惰删除法
不开longlong见祖宗

code:

#include<cstdio>
#include<map>
#define int long long
using namespace std;
inline bool idigit(char x){
    
    return (x<'0'|x>'9')?0:1;}
inline int read()
{
    
    
	int num=0,f=1;
	char c=0;
	while(!idigit(c=getchar())){
    
    if(c=='-')f=-1;}
	while(idigit(c))num=(num<<1)+(num<<3)+(c&15),c=getchar();
	return num*f;
}
inline void write(int x)
{
    
    
	int F[20];
	int tmp=x>0?x:-x;
	if(x<0)putchar('-');
	int cnt=0;
	while(tmp>0){
    
    F[cnt++]=tmp%10+'0';tmp/=10;}
	while(cnt>0)putchar(F[--cnt]);
	if(x==0)putchar('0');
}
struct q
{
    
    
	int id,val;
	bool operator< (const q x){
    
    return val<x.val;}
	bool operator> (const q x){
    
    return val>x.val;}
	void operator= (const q x){
    
    val=x.val,id=x.id;}
}mxx,mnn;
map <int,bool> u;
inline void swap(q &x,q &y){
    
    q z=x;x=y,y=z;}
struct heap
{
    
    
	int tot;
	q a[1000010];
	inline void clean(){
    
    tot=0;}
	inline void up(int x){
    
    while((x>>1)&&(a[x]<a[x>>1]))swap(a[x],a[x>>1]),x>>=1;}
	inline void down(int x){
    
    int r;while((x<<1)<=tot){
    
    r=((x<<1|1)<=tot&&a[x<<1|1]<a[x<<1])?(x<<1|1):(x<<1);if(a[x]>a[r])swap(a[x],a[r]),x=r;else break;}}
	inline int size(){
    
    return tot;}
	inline q top(){
    
    return a[1];}
	inline void pop(){
    
    swap(a[1],a[tot--]),down(1);}
	inline void push(q x){
    
    a[++tot]=x,up(tot);}
}mn;
struct heap_max
{
    
    
	int tot;
	q a[1000010];
	inline void clean(){
    
    tot=0;}
	inline void up(int x){
    
    while((x>>1)&&(a[x]>a[x>>1]))swap(a[x],a[x>>1]),x>>=1;}
	inline void down(int x){
    
    int r;while((x<<1)<=tot){
    
    r=((x<<1|1)<=tot&&a[x<<1|1]>a[x<<1])?(x<<1|1):(x<<1);if(a[x]<a[r])swap(a[x],a[r]),x=r;else break;}}
	inline int size(){
    
    return tot;}
	inline q top(){
    
    return a[1];}
	inline void pop(){
    
    swap(a[1],a[tot--]),down(1);}
	inline void push(q x){
    
    a[++tot]=x,up(tot);}
}mx;
int n,k,t,tot,ans;
signed main()
{
    
    
	n=read(),mx.clean(),mn.clean();
	while(n--)
	{
    
    
		k=read();
		while(k--)t=read(),mxx.id=mnn.id=++tot,mxx.val=mnn.val=t,mx.push(mxx),mn.push(mnn);
		while(u[mx.top().id])mx.pop();
		while(u[mn.top().id])mn.pop();
		ans+=mx.top().val-mn.top().val;
		u[mx.top().id]=u[mn.top().id]=1;
		mx.pop(),mn.pop();
	}
	write(ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zhanglili1597895/article/details/115098096