1. 程式人生 > 其它 >NOIP 模擬 $21\; \rm d$

NOIP 模擬 $21\; \rm d$

題解

題解

很好的貪心題

考慮去掉的矩形一定是幾個 \(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();}