2015ACM/ICPC亚洲区沈阳站 HDU 5517 Triple (二维线段树)

题意 :略

首先我们先假设出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


你可能感兴趣的:(区域赛)