jzoj 5849.【NOIP提高組模擬2018.8.25】d 排序+權值線段樹
阿新 • • 發佈:2019-01-29
Description
Input
Output
Data Constraint
分析:
所有矩陣的交集最大面積顯然為。
我們先按長度排序,列舉一個最小值,然後把長度小於當前值的全部刪掉,再從剩下的裡面把寬度最小的一些矩陣刪掉。其實這個東西可以用一個堆維護。考場上打了一個權值線段樹,感覺好顯然啊。
程式碼:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define LL long long
const int maxn=1e5+7;
const int maxp=1e5;
using namespace std;
int test,n,m;
int t[maxn*4];
LL ans;
struct node{
int x,y;
}a[maxn];
bool cmp(node x,node y)
{
return x.x<y.x;
}
void ins(int p,int l,int r,int x,int k)
{
if (l==r)
{
t[p]+=k;
return ;
}
int mid=(l+r)/2;
if (x<=mid) ins(p*2,l,mid,x,k);
else ins(p*2+1,mid+1,r,x,k);
t[p]=t[p*2]+t[p*2+1];
}
int getrank(int p,int l,int r,int k)
{
if (l==r) return l;
int mid=(l+r)/2;
if (k<=t[p*2]) return getrank(p*2,l,mid,k);
else return getrank(p*2 +1,mid+1,r,k-t[p*2]);
}
int main()
{
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
scanf("%d",&test);
while (test--)
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+n+1,cmp);
ans=0;
for (int i=n;i>0;i--)
{
ins(1,1,maxp,a[i].y,1);
if (i-1>m) continue;
int d=getrank(1,1,maxp,m-(i-1)+1);
ans=max(ans,(LL)a[i].x*(LL)d);
}
for (int i=1;i<=n;i++) ins(1,1,maxp,a[i].y,-1);
printf("%lld\n",ans);
}
}