NOIP 模擬 $21\; \rm Game$
阿新 • • 發佈:2021-07-21
題解
題解
考試的時候遇到了這個題,沒多想,直接打了優先佇列,但沒想到分差竟然不是絕對值,自閉了。
正解:
值域很小,所以我們開個桶,維護當前最大值。
如果新加入的值大於最大值,那麼它肯定直接被下一個人選走。
如果不大於這個最大值,那麼直接選擇最大值,同時對最大值的桶減一,如果最大值的桶為零,那麼往下跳值域直到一個桶不為零的。
因為這個最大值是單調不增的,所以時間複雜度一次是 \(\mathcal O\rm (n)\) 總的就是 \(\mathcal O\rm (nk)\)。
程式碼很好打,知道思路後五分鐘就能打出來
#include<bits/stdc++.h> #define ri register signed #define p(i) ++i using namespace std; namespace IO{ char buf[1<<21],*p1=buf,*p2=buf; #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++ template<typename T>inline void read(T &x) { ri f=1;x=0;register char ch=gc(); while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();} while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();} x=f?x:-x; } } using IO::read; namespace nanfeng{ #define FI FILE *IN #define FO FILE *OUT template<typename T>inline T cmax(T x,T y) {return x>y?x:y;} template<typename T>inline T cmin(T x,T y) {return x>y?y:x;} typedef long long ll; static const int N=1e5+7; int nm[N],T[N],p,k,n,mx,fg=0,num; ll ans1,ans2; inline int main() { // FI=freopen("nanfeng.in","r",stdin); // FO=freopen("nanfeng.out","w",stdout); read(n),read(k); for (ri i(1);i<=n;p(i)) read(nm[i]); for (ri i(1);i<=k;p(i)) { read(p); ans1=ans2=0; num=mx=fg=0; for (ri i(1);i<=p;p(i)) p(T[nm[i]]),mx=cmax(mx,nm[i]); while(1) { if (!fg) ans1+=mx; else ans2+=mx; fg^=1; T[mx]-=1; p(num); while (!T[mx]) --mx; p(p); while (p<=n&&nm[p]>mx) { if (!fg) ans1+=nm[p]; else ans2+=nm[p]; p(num); fg^=1; p(p); } if (p<=n) T[nm[p]]+=1; if (num==n) break; } printf("%lld\n",ans1-ans2); } return 0; } } int main() {return nanfeng::main();}