P4169 [Violet]天使玩偶/SJY摆棋子 cdq分治

  

 

 按照时间分治  只要对四个方向cdq一遍即可

// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//
const int N=1e7+10;
int n,m,S,x,y,x2,y2,z,t[N],op,tim,cnt,cntq,ans[N],lmax,rmax,tot,maxx,maxy;
void add(int x,int v){for(;x<=N;x+=x&-x)t[x]=max(t[x],v);}
int qmax(int x){int ans=0;for(;x;x-=x&-x)ans=max(ans,t[x]);return ans;}
void clean(int x){for(;x<=N;x+=x&-x)t[x]=0;}
struct node
{
    int x,y,t,op,id;
}s[N],temp[N],a[N];
bool cmp(node a,node b){return a.x<b.x||a.x==b.x&&a.y<b.y;}
void cdq(int l,int r)
{
    if(l==r)return;int mid=(l+r)>>1;
    cdq(l,mid);cdq(mid+1,r);
    sort(s+l,s+mid+1,cmp);sort(s+mid+1,s+r+1,cmp);
    int j=l;
    rep(i,mid+1,r)if(s[i].op==2)
    {
        while(j<=mid&&s[j].x<=s[i].x)
        {
            if(s[j].op==1)add(s[j].y,s[j].x+s[j].y);j++;
        }
        int tmp=qmax(s[i].y);
        if(tmp)
        ans[s[i].id]=min(ans[s[i].id],s[i].x+s[i].y-tmp);
    }
    while(--j>=l)
    {
        if(s[j].op==1)clean(s[j].y);
    }
}
bool cmpt(node a,node b){return a.t<b.t;}
void init()
{
    lmax=rmax=tot=0;
    rep(i,1,cnt)if(s[i].op==2)lmax=max(lmax,s[i].x),rmax=max(rmax,s[i].y);
    rep(i,1,cnt)
    {
        if(s[i].x<=lmax&&s[i].y<=rmax)s[++tot]=s[i];
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    rep(i,1,n)
    {
        scanf("%d%d",&x,&y);x++;y++;
        s[++cnt]=(node){x,y,cnt,1,0};
    }
    while(m--)
    {
        scanf("%d%d%d",&op,&x,&y);x++;y++;
        if(op==1)
        {   
            s[++cnt]=(node){x,y,cnt,1,0};
        }
        else 
        {
            s[++cnt]=(node){x,y,cnt,2,++cntq};
        }
    }
    maxx=maxy=1e6+2;
    rep(i,1,cntq)ans[i]=1e9;

    rep(i,1,cnt)a[i]=s[i];
    init();
    cdq(1,tot);

    rep(i,1,cnt)s[i]=a[i],s[i].x=maxx-s[i].x;
    init();
    cdq(1,tot);

    rep(i,1,cnt)s[i]=a[i],s[i].y=maxy-s[i].y;
    init();
    cdq(1,tot);

    rep(i,1,cnt)s[i]=a[i],s[i].x=maxx-s[i].x,s[i].y=maxy-s[i].y;
    init();
    cdq(1,tot);

    rep(i,1,cntq)
    printf("%d\n",ans[i]);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/bxd123/p/11454784.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值