本人的做法是维护两个队列,一个存未吃过的蛇,另一个存吃过的蛇。在某些测试点会与答案产生 1 的差原因大概是最后处理吃完变成最弱的时候出现问题。
然后换 set 过了,不过还是不懂哪里错了。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
int a[N], b[N];
int q1[N], h1, t1;
int q2[N], h2, t2;
int eat(int x, int y){if(a[x]!=a[y])return a[x]<a[y];return x<y;}//y 可以吃掉 x
void calc(int n)
{
int i;
h1 = n + 1, t1 = n * 2, h2 = n * 2 + 1, t2 = n * 2;
for(i=1;i<=n;i++) a[i] = b[i], q1[i+n] = i;
int alive = n;
for(;;)
{
if(alive==1) break;
int mx = 0;
if(h1<=t1&&eat(mx,q1[t1])) mx = q1[t1];
if(h2<=t2&&eat(mx,q2[t2])) mx = q2[t2];
if(h2<=t2&&(h1>t1||eat(q2[h2],q1[h1])))//之前最强的蛇现在最弱
{
int ok = 1, y = alive;
for(;;)
{
if(y==1||(h1<=t1&&eat(q1[h1],q2[h2]))) break;//活了
y--, ok ^= 1;
int x = 0;
if(h1<=t1&&eat(x,q1[t1])) x = q1[t1];
if(h2<=t2&&eat(x,q2[t2])) x = q2[t2];
if(h1<=t1&&x==q1[t1])
{
a[q1[t1]] -= a[q2[h2++]];
q2[--h2] = q1[t1--];
}
else
{
a[q2[t2]] -= a[q2[h2++]];
q2[--h2] = q2[t2--];
}
}
if(!ok) alive++;//刚刚的那条蛇选择不吃
break;
}
else//最强的蛇吃,如果不行则撤销
{
if(h1<=t1&&mx==q1[t1])
{
a[q1[t1]] -= a[q1[h1++]];
q2[--h2] = q1[t1--];
}
else
{
a[q2[t2]] -= a[q1[h1++]];
q2[--h2] = q2[t2--];
}
alive--;
}
}
cout<<alive<<'\n';
}
int main()
{
int t, n, i, j;cin>>t;
for(i=1;i<=t;i++)
{
if(i==1)
{
cin>>n;
for(j=1;j<=n;j++) cin>>b[j];
}
else
{
cin>>j;
while(j--)
{
int x, y;cin>>x>>y;
b[x] = y;
}
}
calc(n);
}
return 0;
}