zoukankan      html  css  js  c++  java
  • 千万别用树套树 【题意:有多少线段完全覆盖某一线段【树状数组维护】】【模板题】

    链接:https://ac.nowcoder.com/acm/contest/1108/H

    Description

    Bobo 精通数据结构!他想维护一个线段的集合 S。初始时,S 为空。他会依次进行 q 次操作,操作有 2 种。

    • 类型 1:给出 l, r,向集合 S 中插入线段 [l, r].
    • 类型 2:给出 l, r,询问满足 [x, y]∈S 且 x ≤ l ≤ r ≤ y 的线段 [x, y] 数量。

    帮 Bobo 求出每次询问的答案。

    • 1 ≤ n, q ≤ 105
    • ti ∈ {1, 2}
    • 1 ≤ li ≤ ri ≤ n
    • 对于 ti = 2 的操作,ri − li ≤ 2 成立。
    • 数据组数不超过 10.

    Input

    输入文件包含多组数据,请处理到文件结束。

    每组数据的第一行包含 2 个整数 n 和 q. 其中 n 表示操作中 r 的最大值。

    接下来 q 行中的第 i 行包含 3 个整数 ti, li, ri,表示第 i 个操作属于类型 ti,对应的参数是 li 和 ri.

    Output

    对于每个类型 2 的询问,输出 1 个整数表示对应的数量。

    Sample Input

    1 2
    1 1 1
    2 1 1
    4 4
    1 1 4
    2 2 3
    1 1 4
    2 2 3
    

    Sample Output

    1
    1
    2

    思路:用总线段条数减去左端点大于l和右端点小于r的线段数(这两种情况不会有重合),线段树单点更新,区间求和。

    代码:

     1 #include<bits/stdc++.h>
     2  
     3 using namespace std;
     4 #define int long long
     5 #define N 120000
     6 int n;
     7 struct BIT{
     8     int c[150000];
     9     int lowbit(int x) {return x&-x; }
    10     int getsum(int x){
    11         int res=0;
    12         for(int i=x;i>0;i-=lowbit(i)){
    13             res+=c[i];
    14         }
    15         return res;
    16     }
    17     void add(int x,int y){
    18         for(int i=x;i<=n;i+=lowbit(i)){
    19             c[i]+=y;
    20         }
    21     }
    22 }L,R;
    23 signed main(){
    24     int q;
    25     while(cin>>n>>q){
    26         int cnt=0;// 线段总个数
    27         int A,b,c; 
    28         while(q--){
    29             scanf("%lld%lld%lld",&A,&b,&c);
    30             if(A==1){
    31                 cnt++;
    32                 L.add(b,1);
    33                 R.add(c,1);
    34             }else{
    35                 int ans1=cnt-R.getsum(c-1);
    36                 int ans2=cnt-L.getsum(b);
    37                 int ans=ans1-ans2;
    38                 printf("%lld
    ",ans);
    39             }
    40         }
    41         for(int i=0;i<=n;i++)
    42             L.c[i]=0,R.c[i]=0;
    43     }
    44     return 0;
    45 }
  • 相关阅读:
    efibootmgr命令
    GPT+UEFI双系统引导
    关于元类的一些使用心得
    队列的数组实现
    队列的链表实现
    栈的链表实现
    栈的数组实现
    单链表实现基数排序
    多项式ADT加法乘法——单链表实现
    LeetCode: 476 Number Complement(easy)
  • 原文地址:https://www.cnblogs.com/pengge666/p/11622950.html
Copyright © 2011-2022 走看看