题意 :略
首先我们先假设出a1,b1和a2,b2分别为(1,2),和(2,2)。那么我们发现,其实(1,2)对于答案是根本没有贡献的。
所以对于b相同的,取a最大的即可。
首先我们定义一个矩阵Map[N][N],Map[c'][d']代表当c=c',d=d'的时候,a所能取到的最大值。
那么对于一个点c',d'假如任何的(c''>=c'&&d''>=d'(不包括点(c',d'))如果都没有Map[c''][d'']都小于Map[c'][d'],则这个点是对答案有贡献的。
因为相同的点可能不止一个,所以我们可以开一个辅助矩阵来存储
我们可以用二维线段树来进行查询。
这个问题便解决了
#include
#include
#include
#include
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define llson j<<1,l,mid
#define rrson j<<1|1,mid+1,r
#define maxn 1010
typedef long long ll;
using namespace std;
ll Map[maxn][maxn],Max[maxn*4][maxn*4];
ll fange[maxn][maxn];
ll n,q,t,ans;
void pushup(ll i,ll j)
{
Max[i][j]=max(Max[i][j<<1],Max[i][j<<1|1]);
}
void build_y(ll i,ll u,ll j,ll l,ll r)
{
if(l==r)
{
Max[i][j]=Map[u][l];
return ;
}
ll mid=(l+r)>>1;
build_y(i,u,llson);build_y(i,u,rrson);
pushup(i,j);
}
void build_x(ll i,ll l,ll r)
{
if(l==r)
{
build_y(i,l,1,1,n);
return ;
}
ll mid=(l+r)>>1;
build_x(lson);build_x(rson);
}
ll query_y(ll i,ll j,ll l,ll r,ll y1,ll y2)
{
if(l==y1&&y2==r) return Max[i][j];
ll mid=(l+r)>>1;
if(y2<=mid) return query_y(i,llson,y1,y2);
else if(y1>mid) return query_y(i,rrson,y1,y2);
else return max(query_y(i,llson,y1,mid),query_y(i,rrson,mid+1,y2));
}
void query_x(ll i,ll l,ll r,ll x1,ll x2,ll y1,ll y2)
{
if(l==r)
{
ans=max(ans,query_y(i,1,1,n,y1,y2));
return ;
}
ll mid=(l+r)>>1;
if(x1<=mid) query_x(lson,x1,x2,y1,y2);
if(x2>mid) query_x(rson,x1,x2,y1,y2);
}
struct NODE
{
ll x,y,val;
}a[100010],b[100010];
bool cmp(NODE a,NODE b)
{
return a.val