[]ウィンドウLuoguのP1502の星

Luogu P1502

質問のよく理解される意味が最大とトラップ与えられた矩形を求められています。

しかし、それをやってするのは非常に面倒です。


- 10ポイントからの怒りのクレイジーバースト

アイデアは、より効率的である-各下へスター矩形は、拡大するように形成されているように、上部左から右へ
、限り長方形内のウィンドウの右上隅などの拡張ルールを星をカバーすることができます。単一ポイントの最大値を見つけるために、過去に左から右にスイープ走査線セグメントツリーを維持します。

ウィンドウフレーム上の星で作られた質問面が答えに含まれていないことに注目すべきであるので、全体の質問を行うことは非常に病気になり、

理解とより便利なアプローチは、水平方向と垂直方向の座標に矩形の左下隅として0.5つ星です。

そして、これは矩形を拡大するために、このルールの遵守を確保します。

大きなによるほか、星の座標では、個別の狭い範囲を使用することができます

コードの時間:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define lson root<<1
#define rson root<<1|1
#define ll long long
using namespace std;
struct data
{
    double l,r,x;
    ll flag;
}line[80005];
bool cmp(data a,data b)
{
    if (a.x==b.x) return a.flag<b.flag;
    return a.x<b.x;
    //重点之一,注意权值小的排在前面,因为在矩形的右边界上,这颗星星已经对答案没有贡献了
}
ll tag[80005],tree[80005],n,w,h,x,y,l,cnt,ans,T;
double pnt[80005];
void push_down(ll root,ll l,ll r)
{
    tag[lson]+=tag[root];
    tag[rson]+=tag[root];
    tree[lson]+=tag[root];
    tree[rson]+=tag[root];
    tag[root]=0;    
}*/
void update(ll root,ll l,ll r,double L,double R,ll flag)
{
    if (L<=pnt[l]&&pnt[r]<=R)
    {
        tag[root]+=flag;
        tree[root]+=flag;
        return ;
    }
    if (l+1==r) return ;
    if (R<=pnt[l]||L>=pnt[r]) return ;
    push_down(root,l,r);
    //事实上不需要pd操作也能过。
    ll mid=(l+r)>>1;
    if (L<pnt[mid]) update(lson,l,mid,L,R,flag);
    if (R>pnt[mid]) update(rson,mid,r,L,R,flag);
    //注意离散化后mid仅为下标,而不是坐标。
    tree[root]=max(tree[lson],tree[rson])+tag[root];
}
int main()
{
    scanf("%d",&T);
    for (int q=1;q<=T;q++)
    {
        cnt=0;
        ans=0;
        memset(line,0,sizeof(line));
        memset(pnt,0,sizeof(pnt));
        memset(tree,0,sizeof(tree));
        memset(tag,0,sizeof(tag));
        //记得要初始化
        scanf("%d%d%d",&n,&w,&h);
        for (int i=1;i<=n;i++)
        {
            scanf("%d%d%d",&x,&y,&l);
            line[++cnt].x=x+0.5;line[cnt].l=y+0.5;line[cnt].r=y+h;line[cnt].flag=l;pnt[cnt]=y+h;
            line[++cnt].x=x+w;line[cnt].l=y+0.5;line[cnt].r=y+h;line[cnt].flag=-l;pnt[cnt]=y+0.5;
            //重点之一,对边界的处理
        }
        sort(line+1,line+1+cnt,cmp);
        sort(pnt+1,pnt+1+cnt);
        ll til=unique(pnt+1,pnt+1+cnt)-pnt-1;
        for (int i=1;i<=cnt;i++)
        {
            update(1,1ll,til,line[i].l,line[i].r,line[i].flag);
            ans=max(ans,tree[1]);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/notscience/p/11783401.html