STL-超市抽奖

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/TengWan_Alunl/article/details/83475312

本来是两个一个大根堆一个小根堆来解决的,然而STL选手(雾,星夜的蓝天)使用了multiset进行解决,没想到TLE了两个点,进行一番研究以后,他发现set+unordered_map=更快的multiset。为什么呢?在要插入时,使用unorderd_map来判断当前set中是否已经有该元素,如果有则不再进行插入,只在unorderd_map将其个数加一,反之则插入并加一,如此可将log级别的插入操作转化为均摊O(1)的操作(插入次数减少很多,并且unordered_map查询均摊O(1))。在删除元素时,从unordered_map中减一,并判断该元素是否有剩余,如果还有剩余,则不对set做操作,反之则在set中erase之,原理同上,速度奇快无比,堪称奇技淫巧。

#include<bits/stdc++.h>
#define rep(i,l,r) for(register int i=(l);i<=(r);i++)
#define per(i,r,l) for(register int i=(r);i>=(l);i--)
#define random(l,r) ((l)+rand()%((r)-(l)+1))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf=1e9+10;
inline int read(){
	register int sign=0,v=0; register char c;
	while(!isdigit(c=getchar())) if(c=='-') break;
	if(c=='-') sign=1; else v=c-48;
	while(isdigit(c=getchar())) v=v*10+c-48;
	if(sign==0) return v; else return -v;
}
set<int> s;
unordered_map<int,int> mp;
int n,k,a;
long long ans;
int main(){
	n=read();
	while(n--){
		k=read();
		while(k--){
			a=read();
			if(mp[a]==0) s.insert(a);
			mp[a]++;
		}
		int small=*s.begin(),big=*(--s.end());
		ans+=big-small;
		if(--mp[big]==0) s.erase(big);
		if(--mp[small]==0) s.erase(small);
	}
	printf("%lld\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/TengWan_Alunl/article/details/83475312