zoukankan      html  css  js  c++  java
  • bzoj1935 Tree 园丁的烦恼(二位偏序,CDQ分治+树状数组)

    传送:https://www.lydsy.com/JudgeOnline/problem.php?id=1935

    题意:有$n$个点,$m$个询问,每次询问为一个矩形,问矩形内有多少个点。

    数据范围:$0 le n le 500000$,$0 le m le 500000$,$0 le x_i,y_i le 10000000$

    分析:

    每次都是询问一个矩形内点的个数。可以按照一维排序,另一维用树状数组维护。

    同样,这个题可以转化为二维偏序去做。CDQ分治。

    维护x维有序,另一维用树状数组维护。

    对于每个矩形$x_1,y_1,x_2,y_2$,答案就是$ans(x_2,y_2)-ans(x_1-1,y_2)-ans(x_2,y_1-2)+ans(x_1-1,y_1-1)$。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=5e5+10;
     4 const int maxm=1e7+10;
     5 struct node{
     6     int x,y,type,id;
     7 }a[maxn*5],b[maxn*5];
     8 int tree[maxm],ans[maxn];
     9 int mx,cnt;
    10 int lowbit(int x){
    11     return x&-x;
    12 }
    13 void add(int x,int val){
    14     while (x<=mx){
    15         tree[x]+=val;
    16         x+=lowbit(x);
    17     }
    18 } 
    19 int query(int x){
    20     int res=0;
    21     while (x>0){
    22         res+=tree[x];
    23         x-=lowbit(x);
    24     }
    25     return res;
    26 }
    27 void _clear(int x){
    28     while (x<=mx){
    29         if (tree[x]==0) break;
    30         tree[x]=0;
    31         x+=lowbit(x);
    32     }
    33 }
    34 void cdq(int l,int r){
    35     if (l==r) return ;
    36     int mid=(l+r)>>1;
    37     cdq(l,mid);
    38     cdq(mid+1,r);
    39     int i=l,j=mid+1,kk=l;
    40     while (i<=mid && j<=r){
    41         if(a[i].x<=a[j].x){
    42             if (a[i].type==1) add(a[i].y,1);
    43             b[kk++]=a[i++];    
    44         }
    45         else{
    46             if (a[j].type==2) ans[a[j].id]+=query(a[j].y);
    47             else if (a[j].type==3) ans[a[j].id]-=query(a[j].y);
    48             b[kk++]=a[j++]; 
    49         }
    50     }
    51     while (i<=mid){
    52         if (a[i].type==1) add(a[i].y,1);
    53         b[kk++]=a[i++];    
    54     }
    55     while (j<=r){
    56         if (a[j].type==2) ans[a[j].id]+=query(a[j].y);
    57         else if (a[j].type==3) ans[a[j].id]-=query(a[j].y);
    58         b[kk++]=a[j++]; 
    59     }
    60     for (int i=l;i<=r;i++){
    61         _clear(a[i].y); a[i]=b[i];
    62     }
    63 }
    64 int main(){
    65     int n,m,sx,sy,ex,ey;
    66     scanf("%d%d",&n,&m);
    67     cnt=0; mx=0;
    68     for (int i=1;i<=n;i++){
    69         cnt++;
    70         scanf("%d%d",&a[cnt].x,&a[cnt].y);
    71         a[cnt].x++;a[cnt].y++;
    72         a[cnt].id=i; a[cnt].type=1;
    73         mx=max(mx,a[cnt].y);
    74     }
    75     for (int i=1;i<=m;i++){
    76         scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
    77         sx++; sy++; ex++; ey++;
    78         a[++cnt]={sx-1,sy-1,2,i};
    79         a[++cnt]={ex,ey,2,i};
    80         a[++cnt]={sx-1,ey,3,i};
    81         a[++cnt]={ex,sy-1,3,i};
    82         mx=max(mx,sy);mx=max(mx,ey);
    83         ans[i]=0;
    84     }
    85     cdq(1,cnt);
    86     for (int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    87     return 0;
    88 }
  • 相关阅读:
    github克隆镜像
    python2安装pip(get-pip.py)和pip更新源
    GitHack使用—create_unverified_context报错
    XCTF:shrine(Flask模块注入)
    开机自启动(C#)
    操作xml(C#)
    隐藏到托盘(C#)
    火狐浏览器下请求两次(C#)
    Nancy学习笔记
    jquery纵向抽屉式导航栏
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11180607.html
Copyright © 2011-2022 走看看