[noi1773]function
以统计x坐标的数量为例:x为下标建一棵线段树,然后对每一个区间按照y坐标建一棵可持久化线段树(每一个x只保留最大的一个y),询问时,二分找到这个区间内最大的y以前的点并统计,复杂度为$o(nlog^{2}n)$
还有一种做法是bitset+分块,预处理出:1.第i个块到第j个块的bitdet;2.每一个块的前缀的bitset;3.每一个块的后缀的bitset,根据这个就可以快速求出对应区间的bitset,然后通过左移和右移去除区间外的点,求和即可,时间复杂度$o(n^{2}/32+n\sqrt{n})$
View Code
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 50005 4 #define y1 y11 5 #define T(p) p,1,1,m[p] 6 #define L (k<<1) 7 #define R (L+1) 8 #define mid (l+r>>1) 9 struct ji{ 10 int x,y; 11 bool operator < (const ji &k)const{ 12 return y<k.y; 13 } 14 }a[N]; 15 struct tr{ 16 int k,ls,rs; 17 }f[N*1000]; 18 vector<int>rt[2][N<<2]; 19 vector<ji>v[2][N<<2]; 20 int V,m[2],n,q,p,x1,y1,x2,y2,ans1,ans2,lst[N],X[N],Y[N]; 21 bool cmp(ji x,ji y){ 22 return x.x<y.x; 23 } 24 void update(int &k,int l,int r,int x,int y){ 25 f[++V]=f[k]; 26 k=V; 27 f[k].k+=y; 28 if (l==r)return; 29 if (x<=mid)update(f[k].ls,l,mid,x,y); 30 else update(f[k].rs,mid+1,r,x,y); 31 } 32 int query(int k,int l,int r,int x,int y){ 33 if ((!k)||(l>y)||(x>r))return 0; 34 if ((x<=l)&&(r<=y))return f[k].k; 35 return query(f[k].ls,l,mid,x,y)+query(f[k].rs,mid+1,r,x,y); 36 } 37 void push(int p,int k,int l,int r,int x,int y){ 38 v[p][k].push_back(ji{x,y}); 39 if (l==r)return; 40 if (x<=mid)push(p,L,l,mid,x,y); 41 else push(p,R,mid+1,r,x,y); 42 } 43 void build(int p,int k,int l,int r){ 44 if (l<r){ 45 build(p,L,l,mid); 46 build(p,R,mid+1,r); 47 } 48 sort(v[p][k].begin(),v[p][k].end()); 49 int las=0,root=0; 50 for(int i=0;i<v[p][k].size();i++){ 51 update(root,1,m[p^1],v[p][k][i].y,1); 52 if (lst[v[p][k][i].x])update(root,1,m[p^1],lst[v[p][k][i].x],-1); 53 lst[v[p][k][i].x]=v[p][k][i].y; 54 if ((i+1==v[p][k].size())||(v[p][k][i+1].y!=v[p][k][las].y)){ 55 while (las++<=i)rt[p][k].push_back(root); 56 las--; 57 } 58 } 59 for(int i=0;i<v[p][k].size();i++)lst[v[p][k][i].x]=0; 60 } 61 int query(int p,int k,int l,int r,int x1,int x2,int y1,int y2){ 62 if ((x1>r)||(l>x2))return 0; 63 if ((x1<=l)&&(r<=x2)){ 64 int x=lower_bound(v[p][k].begin(),v[p][k].end(),ji{0,y2+1})-v[p][k].begin()-1; 65 if (x==-1)return 0; 66 return query(rt[p][k][x],1,m[p^1],y1,y2); 67 } 68 return query(p,L,l,mid,x1,x2,y1,y2)+query(p,R,mid+1,r,x1,x2,y1,y2); 69 } 70 int main(){ 71 scanf("%d",&n); 72 for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y); 73 sort(a+1,a+n+1,cmp); 74 for(int i=1;i<=n;i++)X[i]=a[i].x; 75 sort(a+1,a+n+1); 76 for(int i=1;i<=n;i++)Y[i]=a[i].y; 77 m[0]=unique(X+1,X+n+1)-X-1; 78 m[1]=unique(Y+1,Y+n+1)-Y-1; 79 for(int i=1;i<=n;i++){ 80 a[i].x=lower_bound(X+1,X+m[0]+1,a[i].x)-X; 81 a[i].y=lower_bound(Y+1,Y+m[1]+1,a[i].y)-Y; 82 } 83 for(int i=1;i<=n;i++) 84 scanf("%d%d",&q,&p); 85 for(int i=1;i<=q;i++){ 86 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 87 x1=lower_bound(X+1,X+m[0]+1,x1^(p*ans1))-X; 88 y1=lower_bound(Y+1,Y+m[1]+1,y1^(p*ans2))-Y; 89 x2=upper_bound(X+1,X+m[0]+1,x2^(p*ans1))-X-1; 90 y2=upper_bound(Y+1,Y+m[1]+1,y2^(p*ans2))-Y-1; 91 } 92 }