2010年山东省夏令营提高二班模拟赛Test3.促销 题解

来源:互联网 发布:动态锁屏软件 编辑:程序博客网 时间:2024/06/02 16:05

促销

【题目描述】

       某某商场搞了一个促销活动,促销活动以以下方式进行:

1.      一个想要参加活动的顾客将他的发票扔进抽奖箱里。

2.      在每天的最后,从抽奖箱里抽出两张发票:

a)      金额最大的发票a

b)      金额最小的发票b

3.      金额最大的发票的持有者得到a-b的奖金。

每天被抽出的发票都不会再被放回抽奖箱里。

你想知道促销活动结束时一共付出了多少奖金。

 

【输入格式】

       第一行一个N,促销进行的天数;

       接下来N行,第一个数是一个ki,表示第i天收到的发票数;接下来ki个数,每个数是一个发票的金额。

 

【输出格式】

       一个数,整个促销活动过程中一共付出了多少奖金。

 

【样例】

promotion.in

promotion.out

5

3 1 2 3

2 1 1

4 10 5 5 1

0

1 2

19

 

数据规模:

       对于30%的数据,发票总数M不超过2000;

       对于另外20%的数据,每张发票的金额不超过2000;

       对于100%的数据,发票总数M不超过1000000,每张发票的金额不超过1000000。


#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>using namespace std;const int MaxLen = 1000000+2;int N;long long ans;int a[MaxLen];int Big[MaxLen], Sml[MaxLen];bool flag[MaxLen];void Heap_Insert_Big(int pos, int n){while(pos>1 && (a[Big[pos/2]]<a[n] || flag[Big[pos/2]])){Big[pos] = Big[pos/2];pos /= 2;}Big[pos] = n;}void Heap_Insert_Sml(int pos, int n){while(pos>1 && (a[Sml[pos/2]]>a[n] || flag[Sml[pos/2]])){Sml[pos] = Sml[pos/2];pos /= 2;}Sml[pos] = n;}void Heap_Adjust_Big(int s, int e){int pot = Big[s];for(int i = s+s; i<=e; i+=i){if(flag[Big[i]] && flag[Big[i+1]]) break;if(i<e && (!flag[Big[i+1]] && (a[Big[i+1]]>a[Big[i]] || flag[Big[i]]))) ++i;if(a[pot]>=a[Big[i]]) break;Big[s] = Big[i];s = i;}Big[s] = pot;}void Heap_Adjust_Sml(int s, int e){int pot = Sml[s];for(int i = s+s; i<=e; i+=i){if(flag[Sml[i]] && flag[Sml[i+1]]) break;if(i<e && (!flag[Sml[i+1]] && (a[Sml[i+1]]<a[Sml[i]] || flag[Sml[i]]))) ++i;if(a[pot]<=a[Sml[i]]) break;Sml[s] = Sml[i];s = i;}Sml[s] = pot;}void Heap_Clear_Big(bool clear){if(clear) flag[Big[1]] = true;int p;for(p = *a; flag[Big[p]]; --p);int tmp = Big[1];Big[1] = Big[p];Big[p] = tmp;Heap_Adjust_Big(1, *a);}void Heap_Clear_Sml(bool clear){if(clear) flag[Sml[1]] = true;int p;for(p = *a; flag[Sml[p]]; --p);int tmp = Sml[1];Sml[1] = Sml[p];Sml[p] = tmp;Heap_Adjust_Sml(1, *a);}int main() {freopen("promotion.in", "r", stdin); freopen("promotion.out", "w", stdout);cin >> N;for(int n = 1; n<=N; ++n){int k; cin >> k;for(int i = 1; i<=k; ++i){cin >> a[++*a];Heap_Insert_Big(*a, *a);Heap_Insert_Sml(*a, *a);}ans += (a[Big[1]]-a[Sml[1]]);Heap_Clear_Big(true);Heap_Clear_Sml(true);if(flag[Big[1]]) Heap_Clear_Big(false);}cout << ans << endl;fclose(stdin); fclose(stdout); return 0;}


阅读全文
0 0
原创粉丝点击