zoukankan      html  css  js  c++  java
  • TOJ 4105

    题意:有10万个点,10万个询问,没有更新,求L1<=L<=L2,R1<=R<=R2,有多少个,

            其实转换一下:就是求一个矩形 (L1,R1) ----(L2,R2) 中有多少个点(很经典的题)

            这里有比较神奇的做法:基于某种性质。

            解析:

                    首先按照 L坐标排序,每个点 也弄成 (R,R,L,0,I)这种形式

                    矩形形式是: (L2,R2,L,-1,I) ;和

                                      (L2,R2,R+1,1,I);

                那么,先按照L 排序;

    struct Segment{
    int x1,x2;
    int y,t,id;
    Segment(int x1 = 0,int x2 = 0,int y = 0,int t = 0,int id = 0):x1(x1),x2(x2),y(y),t(t),id(id){}
    bool operator < (const Segment &a)const{
    if(y != a.y) return y < a.y;
    return abs(t) > abs(a.t);
    }

    这样;

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N = 100005;
     4 
     5 #define lson l,mid,rt<<1
     6 #define rson mid+1,r,rt<<1|1
     7 #define Mid int mid = (l + r) >> 1
     8 #define root 1,(N - 5),1
     9 
    10 struct Segment{
    11     int x1,x2;
    12     int y,t,id;
    13     Segment(int x1 = 0,int x2 = 0,int y = 0,int t = 0,int id = 0):x1(x1),x2(x2),y(y),t(t),id(id){}
    14     bool operator < (const Segment &a)const{
    15         if(y != a.y) return y < a.y;
    16         return abs(t) > abs(a.t);
    17     }
    18 }ss[N * 3];
    19 int sz;
    20 struct SegmentTree{
    21     int sum[N << 2];
    22     void pushup(int rt){
    23         sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    24     }
    25     void build(int l,int r,int rt){
    26         sum[rt] = 0;
    27         if(l == r) return;
    28         Mid;
    29         build(lson);
    30         build(rson);
    31     }
    32     void update(int loc,int l,int r,int rt){
    33         if(l == r){
    34             sum[rt] ++;
    35             return;
    36         }
    37         Mid;
    38         if(loc <= mid) update(loc,lson);
    39             else update(loc,rson);
    40         pushup(rt);
    41     }
    42     int query(int L,int R,int l,int r,int rt){
    43         if(L <= l && r <= R){
    44                 return sum[rt];
    45         }
    46         Mid;
    47         int res = 0;
    48         if(L <= mid) res += query(L,R,lson);
    49         if(mid + 1 <= R) res += query(L,R,rson);
    50         return res;
    51     }
    52 }sgt;
    53 int res[N];
    54 int main()
    55 {
    56     int n,m,l,r;
    57     int l2,r2;
    58     while(~scanf("%d",&n)){
    59         sz = 0;
    60         for(int i = 0 ; i < n ; i ++){
    61             scanf("%d%d",&l,&r);
    62             ss[sz ++] = Segment(r,r,l,0);
    63         }
    64         scanf("%d",&m);
    65         for(int i = 0 ; i < m ; i ++){
    66             scanf("%d%d%d%d",&l,&r,&l2,&r2);
    67             ss[sz ++] = Segment(l2,r2,l,-1,i);
    68             ss[sz ++] = Segment(l2,r2,r + 1,1,i);
    69         }
    70         
    71         for(int i = 0 ; i < m ; i ++) res[i] = 0;
    72         sgt.build(root);
    73         sort(ss,ss + sz);
    74         for(int i = 0 ; i < sz ; i ++){
    75             if(ss[i].t == 0) sgt.update(ss[i].x1,root);
    76             else if(ss[i].t == -1){
    77                 res[ ss[i].id ] -= sgt.query(ss[i].x1,ss[i].x2,root);
    78             }
    79             else{
    80                 res[ ss[i].id ] += sgt.query(ss[i].x1,ss[i].x2,root);
    81             }
    82         }
    83         
    84         for(int i = 0 ; i < m ; i ++) printf("%d
    ",res[i]);
    85     }
    86     return 0;
    87 }
    View Code

    先直接贴别人代码。

     因为 我们是按照L 排序的,那么首先更新的事L在前的点。而它只可能对后面的点有影响,并且

    是矩形 后面坐标 R1<=R<=R2;的点,因为询问时询问(R1,R2)区间,

    只有一种是不符合的,R1<=R<=R2,但是L<L1的点 是不满足的 (想想)

    于是我们 只有在去除这些更新的点就好了,所以对于会有:

    else if(ss[i].t == -1){
    res[ ss[i].id ] -= sgt.query(ss[i].x1,ss[i].x2,root);
    }

    在l1<=l<=l2的点都更新完了,我们在加上R+1所有的点,就是该矩形内有多少点的答案了,比较难想。

     这道题也因为 区间比较大,所以普通 的二维树状数组 也是不行的

  • 相关阅读:
    SQLSERVER 2008 R2导入XLSX文件错误,提示报错:The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine. (System.Data)
    转-马斯洛需求层次理论
    邮件发送提示错误“0x800CCC0F”,并存留在发件箱
    WIN10系统JAVA环境配置
    转-简单了解Python装饰器实现原理
    set集合
    阿里云服务器地址及端口
    转:苹果手机同步阿里云邮箱日历
    官方:金蝶实际成本在制品分配详解
    官方:金蝶实际成本在制品材料分配详解
  • 原文地址:https://www.cnblogs.com/forgot93/p/4641584.html
Copyright © 2011-2022 走看看