NOIP 模擬 $21\; \rm d$
阿新 • • 發佈:2021-07-22
題解
題解
很好的貪心題
考慮去掉的矩形一定是幾個 \(a\) 最小的,幾個 \(b\) 最小的,列舉去掉幾個 \(a\),剩下的去掉 \(b\)
先對 \(a\) 排序,用小根堆維護 \(b\) ,記錄哪些已經在 \(a\) 中刪了,這些在 \(b\) 中就需要跳過
但跳過時也需要記錄一下曾經跳過,因為以後在放回 \(a\) 時,如果它在 \(b\) 中出現過,直接填坑即可
Code
#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=5e5+7; struct node{int a,b,id;}sq[N]; int vis[N],st[N],vb[N],cnt,T,n,m; ll ans; inline int operator<(const node &n1,const node &n2) {return n1.b>n2.b;} inline int cmp(node n1,node n2) {return n1.a<n2.a;} priority_queue<node> que; inline int main() { // FI=freopen("nanfeng.in","r",stdin); // FO=freopen("nanfeng.out","w",stdout); read(T); for (ri z(1);z<=T;p(z)) { read(n),read(m); ans=0; memset(vis,0,sizeof(vis)); memset(vb,0,sizeof(vb)); for (ri i(1);i<=n;p(i)) read(sq[i].a),read(sq[i].b),sq[i].id=i; sort(sq+1,sq+n+1,cmp); for (ri i(1);i<=m;p(i)) vis[sq[i].id]=1; for (ri i(1);i<=n;p(i)) que.push(sq[i]); while(vis[que.top().id]) vb[que.top().id]=1,que.pop(); ans=cmax(ans,(ll)sq[m+1].a*que.top().b); for (ri i(m);i;--i) { if (!vb[sq[i].id]) { vis[sq[i].id]=0; while(vis[que.top().id]) vb[que.top().id]=1,que.pop(); vb[que.top().id]=vis[que.top().id]=1; que.pop(); while(vis[que.top().id]) vb[que.top().id]=1,que.pop(); ans=cmax(ans,(ll)sq[i].a*que.top().b); } while(!que.empty()) que.pop(); printf("%lld\n",ans); } return 0; } } int main() {return nanfeng::main();}