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
  • 相关阅读:
    Python基础 | pandas中dataframe的整合与形变(merge & reshape)
    Python基础 | pandas中数据的筛选(index & subset)
    Python基础 | 关于“循环”那些事
    Python基础 | 数据文件的读写
    Python基础 | 字符串操作
    如何用数据说谎 How to lie with data
    浅谈“数据敏感度”
    爬虫 | IT桔子互联网公司死亡名单
    从一道面试题谈数据推算方法
    爬虫 | cnblog文章收藏排行榜(“热门文摘”)
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13084784.html
Copyright © 2011-2022 走看看