2018SEERC Points and Rectangles (CDQ分治)
题:http://codeforces.com/gym/101964/problem/K
分析:https://blog.csdn.net/qq_43202683/article/details/98115901
#include<bits/stdc++.h> using namespace std; typedef long long ll; inline int read(){ int sum=0,x=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') x=0; ch=getchar(); } while(ch>='0'&&ch<='9') sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar(); return x?sum:-sum; } inline void write(ll x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } #define pb push_back #define lowbit(x) (x&(-x)) const int M=5e5+5; int ans[M]; int tree[M]; void add(int i,int x){ while(i<M) tree[i]+=x,i+=(i&(-i)); return ; } int query(int i){ int res=0; while(i){ res+=tree[i]; i-=(i&(-i)); } return res; } struct node{ int x,y,op,id; bool operator <(const node &b)const{ return id<b.id; } }a[M],temp[M]; vector<pair<int, int> > book; void cdq1(int l, int r)//算点对矩阵的贡献(小于等于) { if(r-l<=1) return; int midd = (r+l)>>1; cdq1(l, midd); cdq1(midd, r); int i= l,j= midd,n = 0; while(i< midd &&j< r){ if(a[i].x <= a[j].x){ if(a[i].op == 1){ add(a[i].y, 1); book.push_back(make_pair(a[i].y, 1)); } temp[n++] = a[i++]; } else{ if(a[j].op==2){ ans[a[j].id]+=query(a[j].y); } else if(a[j].op==3) ans[a[j].id]-=query(a[j].y); temp[n++]=a[j++]; } } while(i<midd) temp[n++] = a[i++]; while(j<r){ if(a[j].op == 2) ans[a[j].id] += query(a[j].y); else if(a[j].op == 3) ans[a[j].id] -= query(a[j].y); temp[n++]=a[j++]; } for(i =l;i<r;++i) a[i]=temp[i - l]; for(i = 0; i <book.size(); ++i) add(book[i].first, -book[i].second); book.clear(); return; } void cdq2(int l,int r) { if(r-l<= 1) return; int midd=(l+r)>>1; cdq2(l,midd); cdq2(midd,r); int i= l,j=midd,n=0; while(i<midd&&j<r){ if(a[i].x<a[j].x){ if(a[i].op == 2){ add(a[i].y,1); book.pb(make_pair(a[i].y, 1)); } else if(a[i].op==3){ add(a[i].y,-1); book.pb(make_pair(a[i].y,-1)); } temp[n++]=a[i++]; } else{ if(a[j].op == 1){ ans[a[j].id] +=query(a[j].y-1); } temp[n++]=a[j++]; } } while(i<midd) temp[n++]=a[i++];//temp[o++] = e[lp++]?? = temp[lp++],debug??? while(j<r){ if(a[j].op == 1) { ans[a[j].id] +=query(a[j].y - 1); } temp[n++]=a[j++]; } for(i=l;i<r;i++) a[i]=temp[i-l]; for(i=0;i<book.size();i++) add(book[i].first,-book[i].second); book.clear(); return; } int lisan[M<<2]; int main(){ int n=read(); int tot=0,num=0; for(int i=0;i<n;i++){ int op=read(); if(op==1){ a[tot].x=read(),a[tot].y=read(); a[tot].op=1,a[tot].id=i; lisan[++num]=a[tot].x,lisan[++num]=a[tot].y; tot++; } else{ int x1=read(),y1=read(),x2=read(),y2=read(); a[tot].op=2,a[tot].x=x1-1,a[tot].y=y1-1,a[tot].id=i,tot++; a[tot].op=2,a[tot].x=x2,a[tot].y=y2,a[tot].id=i,tot++; a[tot].op=3,a[tot].x=x1-1,a[tot].y=y2,a[tot].id=i,tot++; a[tot].op=3,a[tot].x=x2,a[tot].y=y1-1,a[tot].id=i,tot++; lisan[++num]=x1-1,lisan[++num]=x2,lisan[++num]=y1-1,lisan[++num]=y2; } } sort(lisan+1,lisan+num+1); int m=unique(lisan+1,lisan+1+num)-lisan-1; for(int i=0;i<tot;i++){ a[i].x=lower_bound(lisan+1,lisan+1+m,a[i].x)-lisan; a[i].y=lower_bound(lisan+1,lisan+1+m,a[i].y)-lisan; // cout<<a[i].x<<"~~~~"<<a[i].y<<endl; } cdq1(0,tot); sort(a,a+tot); cdq2(0,tot); ll ANS=0ll; for(int i=0;i<n;i++){ ANS+=ans[i]; write(ANS); puts(""); } return 0; }