【JZOJ A组】 d

Description

这里写图片描述

Input

这里写图片描述

Output

这里写图片描述

Sample Input

见下发文件

Sample Output

见下发文件

Data Constraint

【JZOJ A组】 d_第1张图片

思路

一开始胡想法是二分答案套树状数组,结果玄学WA

最大化 min{a_i}*min{b_i},那肯定贪心的选择若干个 a_i 最小的矩形和若干个 b_i最小的矩形删除。

枚举删除几个 a_i最小的矩形,剩下的删除 b_i最小的矩形,用排序预处理min{a_i},用堆维护 min{b_i}。

代码

#include
#include
#include
using namespace std;
const int maxn=100077;
int t,n,m,tr[maxn];
struct A
{
    int x,y;
}a[maxn];
bool cmp(A a,A b)
{
    return (a.xint lowbit(int x)
{
    return x&-x;
}
void ins(int x,int d)
{
    for(int i=x; i<=100000; i+=i&-i) tr[i]+=d;
}
int query(int x)
{
    int s=0;
    for(int i=x; i; i-=lowbit(i)) s+=tr[i];
    return s;
}
bool check(int x,int y) { return (query(y-1)+x<=m)?1:0; }
int main()
{
    freopen("d.in","r",stdin);
    freopen("d.out","w",stdout);
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d%d",&n,&m);
        int mxx=0,p=0,mxy=0; long long ans=0;
        for(int i=1; i<=n; i++) scanf("%d%d",&a[i].x,&a[i].y),mxx=max(mxx,a[i].x),mxy=max(mxy,a[i].y);
        sort(a+1,a+n+1,cmp);
        for(int i=1; i<=n; i++) ins(a[i].y,1);
        for(int i=1; i<=n; i++)
        {
            int k=i,l=1,r=mxy,mx=0;
            while(a[k].x==a[k+1].x&&kwhile(l<=r)
            {
                int mid=(l+r)>>1;
                if (check(p,mid)) mx=mid,l=mid+1; else r=mid-1;
            }
            for(int j=i; j<=k; j++) ins(a[j].y,-1),p++; 
            ans=max(ans,1ll*a[i].x*mx);
            i=k;
        }
        printf("%lld\n",ans);
    }
}

你可能感兴趣的:(题解)