BZOJ 2683: 简单题 [CDQ分治]

同上题

那你为什么又发一个?

因为我用另一种写法又写了一遍...

不用排序,$CDQ$分治的时候归并排序

快了1000ms...

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=1e6+5;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,op,m;
struct Operation{
    int x,y,v,id;
    int qid,op;
    Operation():op(0){}
    Operation(int x,int y,int v,int id,int qid,int op):
        x(x),y(y),v(v),id(id),qid(qid),op(op){}
    bool operator <(const Operation &r)const{
        return x==r.x?op<r.op:x<r.x;
    }
}a[N],t[N];
int ans[N],qid;
void devideQuery(){
    int x1=read()-1,y1=read()-1,x2=read(),y2=read();
    qid++;
    m++;a[m]=Operation(x2,y2,1,m,qid,1);
    m++;a[m]=Operation(x1,y2,-1,m,qid,1);
    m++;a[m]=Operation(x2,y1,-1,m,qid,1);
    m++;a[m]=Operation(x1,y1,1,m,qid,1);
}
int c[N];
inline int lowbit(int x){return x&-x;}
inline void add(int p,int v){for(;p<=n;p+=lowbit(p)) c[p]+=v;}
inline int sum(int p){
    int re=0;
    for(;p;p-=lowbit(p)) re+=c[p];
    return re;
}
void CDQ(int l,int r){
    if(l==r) return;
    int mid=(l+r)>>1;
    CDQ(l,mid);CDQ(mid+1,r);
    int i=l,j=mid+1,p=l;
    while(i<=mid||j<=r){
        if(j>r||(i<=mid&&a[i]<a[j])){
            if(!a[i].op) add(a[i].y,a[i].v);
            t[p++]=a[i++];
        }else{
            if(a[j].op) ans[a[j].qid]+=a[j].v*sum(a[j].y);
            t[p++]=a[j++];
        }
    }
    for(int i=l;i<=r;i++) if(a[i].id<=mid&&!a[i].op) add(a[i].y,-a[i].v);
    for(int i=l;i<=r;i++) a[i]=t[i];
}
int main(){
    freopen("in","r",stdin);
    n=read();
    m=0;
    while(true){
        op=read();
        if(op==1) a[++m].x=read(),a[m].y=read(),a[m].v=read(),a[m].id=m;
        else if(op==2) devideQuery();
        else break;
    }
    CDQ(1,m);
    for(int i=1;i<=qid;i++) printf("%d\n",ans[i]);
}

 

posted @ 2017-02-24 08:06  Candy?  阅读(345)  评论(0编辑  收藏  举报