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]); }
Copyright:http://www.cnblogs.com/candy99/