1. 程式人生 > >[整體二分 樹狀陣列套線段樹] BZOJ 2674 Attack

[整體二分 樹狀陣列套線段樹] BZOJ 2674 Attack

大暴力啊 96s+卡過 

//本地明明44s+

//要了資料才知道相對頂點可以不是左下和右上

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;

inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
    return *p1++;
}

inline void read(int &x){
    char c=nc(),b=1;
    for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
    for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

inline void read(char &x){
    for (x=nc();x!='S' && x!='Q';x=nc());
}

const int N=60005,ND=5000005;

int sx[N],sy[N],sp[N]; int icnt;

inline int Bin1(int *a,int x){
    return lower_bound(a+1,a+a[0]+1,x)-a;
}

inline int Bin2(int *a,int x){
    return upper_bound(a+1,a+a[0]+1,x)-a-1;
}

int Stk[ND],pnt;
inline void Init(){ for (int i=ND-1;i;i--) Stk[++pnt]=i; }
inline int  New(){ return Stk[pnt--]; }
inline void Del(int x) { Stk[++pnt]=x; }

int ls[ND],rs[ND],sum[ND];

void Add(int &x,int l,int r,int t,int s){
    if (!x) x=New(); int mid=(l+r)>>1;
    if (l==r) {
        sum[x]+=s;
        if (!sum[x]) Del(x),x=0;
        return;
    }
    if (t<=mid)
        Add(ls[x],l,mid,t,s);
    else
        Add(rs[x],mid+1,r,t,s);
    sum[x]=sum[ls[x]]+sum[rs[x]];
    if (!sum[x]) Del(x),x=0;
}

int Query(int x,int l,int r,int L,int R){
    if (!x) return 0; int mid=(l+r)>>1;
    if (L<=l && r<=R) return sum[x];
    if (R<=mid)
        return Query(ls[x],l,mid,L,R);
    else if (L>mid)
        return Query(rs[x],mid+1,r,L,R);
    else
        return Query(ls[x],l,mid,L,mid)+Query(rs[x],mid+1,r,mid+1,R);
}

namespace BIT{
    #define lowbit(x) ((x)&-(x))
    int maxn;
    int c[N];
    inline void init(int n){
        maxn=n;
    }
    inline void add(int x,int y,int r){
        for (int i=x;i<=maxn;i+=lowbit(i))
            Add(c[i],1,icnt,y,r);
    }
    inline int sum(int x,int L,int R){
        int ret=0;
        for (int i=x;i;i-=lowbit(i))
            ret+=Query(c[i],1,icnt,L,R);
        return ret;
    }
}

int n,m;

const int E=100005;

struct event{
    int f,x1,y1,x2,y2,p,k,idx;
    event(){ }
    event(int f,int x1,int y1,int x2,int y2,int p,int k,int idx):f(f),x1(x1),x2(x2),y1(y1),y2(y2),k(k),p(p),idx(idx) {}
}eve[E],tmpl[E],tmpr[E];
int tot,il,ir;

int _x[N],_y[N],_p[N];
int ans[N],qq;

inline void Solve(int l,int r,int L,int R)
{
    if (l>r) return;
    if (L==R){
        for (int i=l;i<=r;i++)
            if (eve[i].f)
                ans[eve[i].idx]=L;
        return;
    }
    int mid=(L+R)>>1,tem; il=ir=0;
    for (int i=l;i<=r;i++)
        if (!eve[i].f){
            if (eve[i].p<=mid)
                BIT::add(eve[i].x1,eve[i].y1,eve[i].k),tmpl[++il]=eve[i];
            else
                tmpr[++ir]=eve[i];
        }else{
            tem=BIT::sum(eve[i].x2,eve[i].y1,eve[i].y2)-BIT::sum(eve[i].x1-1,eve[i].y1,eve[i].y2);
            if (tem<eve[i].k)
                eve[i].k-=tem,tmpr[++ir]=eve[i];
            else
                tmpl[++il]=eve[i];
        }
    for (int i=r;i>=l;i--)
        if (!eve[i].f && eve[i].p<=mid)
            BIT::add(eve[i].x1,eve[i].y1,-eve[i].k);
    int top=l-1,mi;
    for (int i=1;i<=il;i++) eve[++top]=tmpl[i]; mi=top;
    for (int i=1;i<=ir;i++) eve[++top]=tmpr[i];
    Solve(l,mi,L,mid);
    Solve(mi+1,r,mid+1,R);
}

int main()
{
    char order;
    int u,v,x1,x2,y1,y2,k;
    freopen("t.in","r",stdin);
    freopen("t.out","w",stdout);
    Init();
    read(n); read(m);
    for (int i=1;i<=n;i++)
    {
        read(_x[i]),read(_y[i]),read(_p[i]);
        sx[++sx[0]]=_x[i],sy[++sy[0]]=_y[i],sp[++sp[0]]=_p[i];
    }
    sort(sx+1,sx+sx[0]+1); sx[0]=unique(sx+1,sx+sx[0]+1)-sx-1;
    sort(sy+1,sy+sy[0]+1); sy[0]=unique(sy+1,sy+sy[0]+1)-sy-1;
    sort(sp+1,sp+sp[0]+1); sp[0]=unique(sp+1,sp+sp[0]+1)-sp-1;
    for (int i=1;i<=n;i++)
    {
        _x[i]=Bin1(sx,_x[i]); _y[i]=Bin1(sy,_y[i]); _p[i]=Bin1(sp,_p[i]);
        eve[++tot]=event(0,_x[i],_y[i],0,0,_p[i],1,0);
    }
    for (int i=1;i<=m;i++)
    {
        read(order);
        if (order=='S')
        {
            read(u); read(v); u++; v++; if (u==v) continue;
            eve[++tot]=event(0,_x[u],_y[u],0,0,_p[u],-1,0);
            eve[++tot]=event(0,_x[u],_y[u],0,0,_p[v],1,0);
            eve[++tot]=event(0,_x[v],_y[v],0,0,_p[v],-1,0);
            eve[++tot]=event(0,_x[v],_y[v],0,0,_p[u],1,0);
            swap(_p[u],_p[v]);
        }
        else
        {
            read(x1); read(y1); read(x2); read(y2); read(k);
            if (x1>x2) swap(x1,x2);
            if (y1>y2) swap(y1,y2);
            x1=Bin1(sx,x1); x2=Bin2(sx,x2);
            y1=Bin1(sy,y1); y2=Bin2(sy,y2);
            if (x1>x2 || y1>y2)
                ans[++qq]=sp[0]+1;
            else
                eve[++tot]=event(1,x1,y1,x2,y2,0,k,++qq);
        }
    }
    icnt=sy[0]; BIT::init(sx[0]);
    Solve(1,tot,1,sp[0]+1);
    for (int i=1;i<=qq;i++)
        if (ans[i]==sp[0]+1)
            printf("It doesn't exist.\n");
        else
            printf("%d\n",sp[ans[i]]);
    return 0;
}