• bzoj 1935 Tree 园丁的烦恼


    题目大意:

    一些点,每次查询一个矩形内有多少个点

    思路:

    因为空间太大

    所以不能用什么二维树状数组

    需要把这些点和所有查询的矩阵的左下和右上离线下来

    先离散化

    然后每个子矩阵像二维前缀和那样查询

    按照x升序加入点,对于矩阵的点查询

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 500100
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 int n,c[MAXN*3],vis[MAXN],m,cnt,k,ans[MAXN];
    21 struct data 
    22 {
    23     int x,y,pos,yy;
    24 }g[MAXN*3],a[MAXN*3];
    25 bool cmp1(data a,data b)
    26 {
    27     if(a.x<b.x) return 1;
    28     if(a.x>b.x) return 0;
    29     if(a.x==b.x)
    30     {
    31         if(a.pos<=n&&b.pos>n) return 1;
    32         if(a.pos>n&&b.pos<=n) return 0;
    33         return a.y<b.y;
    34     }
    35 }
    36 bool cmp2(data a,data b) {return a.y<b.y||(a.y==b.y&&a.x<b.x);}
    37 int lowbit(int x) {return x&(-x);}
    38 void add(int x) {for(int i=x;i<=k;i+=lowbit(i)) c[i]++;}
    39 int query(int x) {int res=0;for(int i=x;i;i-=lowbit(i)) res+=c[i];return res;}
    40 int main()
    41 {
    42     n=read(),m=read();
    43     for(int i=1;i<=n;i++)
    44         a[i].pos=g[i].pos=i,g[i].x=read(),g[i].y=read();
    45     for(int i=n+1;i<=n+2*m;i++)
    46         a[i].pos=g[i].pos=i,g[i].x=read(),g[i].y=read();
    47     sort(g+1,g+n+2*m+1,cmp2);
    48     g[0].x=g[0].y=-1,cnt=0;
    49     //离散化---------------------------------------------------------
    50     for(int i=1;i<=n+2*m;i++)
    51     {
    52         if(g[i].y!=g[i-1].y) a[g[i].pos].y=++cnt;
    53         else a[g[i].pos].y=cnt;
    54     }
    55     k=cnt+5;sort(g+1,g+n+2*m+1,cmp1);cnt=0;
    56     for(int i=1;i<=n+2*m;i++)
    57     {
    58         if(g[i].x!=g[i-1].x) a[g[i].pos].x=++cnt;
    59         else a[g[i].pos].x=cnt;
    60     }
    61     //对于每个子矩阵的点需要记录另一个点的纵坐标---------------------
    62     for(int i=1;i<=2*m;i+=2)
    63         {--a[i+n].x,a[i+n].yy=a[i+1+n].y,a[i+1+n].yy=a[i+n].y;}
    64     sort(a+1,a+n+m*2+1,cmp1);
    65     for(int i=1;i<=n+2*m;i++)
    66     {
    67         if(a[i].pos>n)//如果是查询 
    68         {
    69             int h=(a[i].pos-n+1)>>1;vis[h]++;
    70             if(vis[h]==1) ans[h]=query(a[i].y-1)-query(a[i].yy);//左下角的点 
    71             if(vis[h]==2) ans[h]+=query(a[i].y)-query(a[i].yy-1);//右上角的点 
    72         }
    73         else add(a[i].y);//不是查询的点
    74     }
    75     for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    76 }
    View Code
  • 相关阅读:
    初探并行线程的三种写法
    Revit2017二次开发-打印机配置
    test错误记录
    自行车出租系统错误集2
    错误记录-spring+mybatis
    Windows(64位IIS)未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序
    sqlDeveloper连接oracle
    Apriori算法-java
    Apriori算法-位运算-C语言
    Apriori算法-数组-C语言
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8067018.html
Copyright © 2020-2023  润新知