zoukankan      html  css  js  c++  java
  • [BZOJ1935][SHOI2007]Tree 园丁的烦恼(离线+树状数组)

    题意

    给出第一象限的n个点,有m次询问,每次询问一个矩形中的点的个数.(0<=n,m<=500000,0<=xi,yi<=10000000)

    题解

    一眼望去不可做。

    用二位前缀和的思想,一个矩形可以用以坐标轴为一对临边的四个矩形加减得到。

    考虑离线,离散化。所以我们要求的只是若干个以坐标轴为一对临边的矩形的权值。

    但还是不可做。

    转化为序列问题,我们要求的矩形面积,其实就是每行前缀和的一段连续地和。

    具体一些,就是,算出每一行的前缀和,对于横坐标相等的前缀和,我们维护他们,矩形的面积,就是这些前缀和的前面一段。同时维护一个横坐标指针x,在x右移时前缀和加上横坐标为x的点。我们发现这些操作可以用树状数组维护。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 using namespace std;
      7 int const N=7001000;
      8 int head[N],hed[N],c[N],n,m;
      9 int cnt,cntx,cnty,totx,toty,ans[N],tot,x[N],y[N];
     10 struct zb{
     11     int x,y;
     12 }zb[N];
     13 struct ask{
     14     int x,xx,y,yy;
     15 }q[N];
     16 struct edge{
     17     int to,nxt;
     18 }e[N];
     19 struct hhh{
     20     int to,nxt,w,id;
     21 }f[N];
     22 void add(int u,int v){
     23     cnt++;
     24     e[cnt].nxt=head[u];
     25     e[cnt].to=v;
     26     head[u]=cnt;
     27 }
     28 void ad(int u,int v,int c,int x){
     29     tot++;
     30     f[tot].nxt=hed[u];
     31     f[tot].w=c;
     32     f[tot].to=v;
     33     f[tot].id=x;
     34     hed[u]=tot;
     35 }
     36 int lowbit(int x){
     37     return x&-x;
     38 }
     39 void update(int x,int w){
     40     for(int i=x;i<=cnty;i+=lowbit(i)){
     41         c[i]+=1;
     42     }
     43 }
     44 int check(int x,int w){
     45     if(x==0)return 0;
     46     int ans=0;
     47     for(int i=x;i>=1;i-=lowbit(i)){
     48         ans+=c[i];
     49     }
     50     return ans*w;
     51 }
     52 void work(){
     53     for(int i=1;i<=cntx;i++){
     54         for(int j=head[i];j;j=e[j].nxt){
     55             int v=e[j].to;
     56             update(v,1);
     57         }
     58         for(int j=hed[i];j;j=f[j].nxt){
     59             int v=f[j].to;
     60             ans[f[j].id]+=check(v,f[j].w);
     61         }
     62     }
     63 }
     64 int main(){
     65     scanf("%d%d",&n,&m);
     66     for(int i=1;i<=n;i++){
     67         scanf("%d%d",&zb[i].x,&zb[i].y);
     68         x[++totx]=zb[i].x;
     69         y[++toty]=zb[i].y;
     70     }
     71     for(int i=1;i<=m;i++){
     72         scanf("%d%d%d%d",&q[i].x,&q[i].y,&q[i].xx,&q[i].yy);
     73         x[++totx]=q[i].x;
     74         y[++toty]=q[i].y;
     75         x[++totx]=q[i].xx;
     76         y[++toty]=q[i].yy;
     77     }
     78     sort(x+1,x+1+totx);
     79     sort(y+1,y+1+toty);
     80     cntx=unique(x+1,x+1+totx)-(x+1);
     81     cnty=unique(y+1,y+1+toty)-(y+1);
     82     for(int i=1;i<=n;i++){
     83         zb[i].x=lower_bound(x+1,x+1+cntx,zb[i].x)-x;
     84         zb[i].y=lower_bound(y+1,y+1+cnty,zb[i].y)-y;
     85         add(zb[i].x,zb[i].y);
     86     }
     87     for(int i=1;i<=m;i++){
     88         q[i].x=lower_bound(x+1,x+1+cntx,q[i].x)-x;
     89         q[i].y=lower_bound(y+1,y+1+cnty,q[i].y)-y;
     90         q[i].xx=lower_bound(x+1,x+1+cntx,q[i].xx)-x;
     91         q[i].yy=lower_bound(y+1,y+1+cnty,q[i].yy)-y;
     92         ad(q[i].x-1,q[i].y-1,1,i);
     93         ad(q[i].xx,q[i].yy,1,i);
     94         ad(q[i].x-1,q[i].yy,-1,i);
     95         ad(q[i].xx,q[i].y-1,-1,i);
     96     }
     97     work();
     98     for(int i=1;i<=m;i++){
     99         printf("%d
    ",ans[i]);
    100     }
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    mysql安装及初始密码问题
    centos7上安装erlang22.1
    共享文件夹设置
    putty免密登录
    重新开始
    单任务多线程 安全
    线程池
    多线程
    commons-IO
    打印流
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9350752.html
Copyright © 2011-2022 走看看