[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})$
 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 }
View Code

 

posted @ 2020-06-10 14:13  PYWBKTDA  阅读(185)  评论(0编辑  收藏  举报