zoukankan      html  css  js  c++  java
  • [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+nsqrt{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
  • 相关阅读:
    BZOJ 2212/BZOJ 3702
    BZOJ 4761 Cow Navigation
    BZOJ 3209 花神的数论题
    BZOJ 4760 Hoof, Paper, Scissors
    BZOJ 3620 似乎在梦中见过的样子
    BZOJ 3940 Censoring
    BZOJ 3942 Censoring
    BZOJ 3571 画框
    BZOJ 1937 最小生成树
    BZOJ 1058 报表统计
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13084784.html
Copyright © 2011-2022 走看看