2020-8-7CF反思

打的是真的差,开场正序开题,然后A读了 20 20 20 分钟/youl,然后才A。

然后就开了B题,B题可谓是雪崩,题目大概是这样的,给定一些木棒,要求支持动态插入和删除,每次操作结束后回答是否能摆出一个正方形和一个长方形。

很显然,最后为成的木棒显然最多只跟 3 3 3 种不同长度的木棒有关,所以我们只需求出出现次数第 1 1 1 多的木棒、第 2 2 2 多的木棒和第 3 3 3 多的木棒。

这道题目不需要离散化,题目保证木棒长度 a i ≤ 1 0 5 a_i \leq 10^5 ai105,所以我们直接开个数组记录就好了,维护最大值、次大值、次次大值我是用 multiset \texttt{multiset} multiset 维护的。

然而,事情没有我想的那么简单,我 WA \text{WA} WA 了。

这是我当时的代码


// Problem: B. Applejack and Storages
// Contest: Codeforces - Codeforces Round #662 (Div. 2)
// URL: https://codeforc.es/contest/1393/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include 
#define int long long
using namespace std;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int h[100010];
multiset<int>q;
signed main(){
	memset(h,0,sizeof(h));
	int n;read(n);
	for(int i=1;i<=n;i++){
		int x;read(x);
		h[x]++;
	}
	for(int i=1;i<=100000;i++)
		if(h[i]>=2)q.insert(-h[i]);
	int m;read(m);
	while(m--){
		char ch;int xx;
		cin>>ch>>xx;
		if(ch=='+'){
			if(h[xx]>=2)q.erase(-h[xx]);
			h[xx]++;
			if(h[xx]>=2)q.insert(-h[xx]);
		}else{
			if(h[xx]>=2)q.erase(-h[xx]);
			h[xx]--;
			if(h[xx]>=2)q.insert(-h[xx]);
		}
		int x=0,y=0,z=0,tot=0;
		for(int i:q){
			if(++tot>3)break;
			if(tot==1)x=-i;
			if(tot==2)y=-i;
			if(tot==3)z=-i;
		}
		int a=x/2,b=y/2,c=z/2;
		if(a<2)puts("NO");
		else if(a-2+b+c<2)puts("NO");
			else puts("YES");
	}
	return 0;
}

我自闭了,这个代码十分地有道理,但是直到比赛结束我一直没找到这个代码有什么问题。

直到比赛结束,我才恍然大悟——我看了看我 WA \text{WA} WA 的数据,加了几句调试语句,一个大胆的想法从我脑子里蹦了出来—— multiset \texttt{multiset} multiset e r a s e erase erase 函数会把所有只为 x x x 的数删除!

问了一下美国队长,竟然真的是这样,哎,我的 92 92 92 Rating啊,就这样没了,泪目……

这也算是 92 92 92 Rating换来的血的教训吧……当然,还好我的草名保住了。

你可能感兴趣的:(反思)