题意
传说中,东海龙宫有一副绝世法宝——n张神迹卡牌,每张卡牌上都写着一个数字。哪吒闹海时,想要施法将龙宫这n张卡牌毁灭,若当前剩余的卡牌数量为k,哪吒就可以施法将所有数字为k的卡牌销毁,这样的操作可以一直进行到没有卡牌可以被毁灭为止。
但哪吒发现,只进行这样的操作可能没办法把所有卡牌消灭,于是他借来了师父太乙真人的法宝,使用一次可以将一张卡牌上的数字改变成他想要的任意一个其他数字。
但是东海龙王发现了哪吒的企图,于是东海龙王会进行m次修改操作,第i次将第(x_i)张卡牌的数字改变为(y_i) ,每次东海龙王进行一次操作后,哪吒都想知道至少使用多少次法宝才可以将所有卡牌消灭。
思路
设(cnt[i])为i出现的次数,那么删除i后显然会到(i-cnt[i]+1),那么维护一下每一个位置上的连通性即可。
代码
#include <bits/stdc++.h>
using namespace std;
namespace StandardIO {
template<typename T> inline void read (T &x) {
x=0;T f=1;char c=getchar();
for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
x*=f;
}
template<typename T> inline void write (T x) {
if (x<0) putchar('-'),x=-x;
if (x>=10) write(x/10);
putchar(x%10+'0');
}
}
using namespace StandardIO;
namespace Solve {
const int N=200200;
int n,m,ans;
int a[N],cnt[N],tot[N];
inline void MAIN () {
read(n),read(m);
for (register int i=1; i<=n; ++i) {
read(a[i]),++cnt[a[i]];
if (a[i]-cnt[a[i]]+1>0) if ((++tot[a[i]-cnt[a[i]]+1])==1) ++ans;
}
while (m--) {
int x,y;
read(x),read(y);
if (a[x]-cnt[a[x]]+1>0) if ((--tot[a[x]-cnt[a[x]]+1])==0) --ans;
--cnt[a[x]],a[x]=y,++cnt[a[x]];
if (a[x]-cnt[a[x]]+1>0) if ((++tot[a[x]-cnt[a[x]]+1])==1) ++ans;
write(n-ans),putchar('
');
}
}
}
int main () {
Solve::MAIN();
}