千万别用树套树 【题意:有多少线段完全覆盖某一线段【树状数组维护】】【模板题】

链接: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\n",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 }

原文地址:https://www.cnblogs.com/pengge666/p/11622950.html

时间: 2024-12-26 00:27:33

千万别用树套树 【题意:有多少线段完全覆盖某一线段【树状数组维护】】【模板题】的相关文章

ACdreamoj 1011(树状数组维护字符串hash前缀和)

题目链接:http://acdream.info/problem? pid=1019 题意:两种操作,第一种将字符串某个位置的字符换为还有一个字符.另外一种查询某个连续子序列是否是回文串: 解法:有两种hash的办法,所以写了两种解法;首先hash是x1 * p^1+ x2*p^2 +x3*p^3...能够用树状数组维护前缀和,维护两个串,一个是正串.还有一个是反串用于比較.比較时候乘以对应的p倍数推断是否相等. 刘汝佳白书上的hash方法处理这道题更复杂:改动i会对后缀j产生的影响为a*p^(

poj 3321:Apple Tree(树状数组,提高题)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18623   Accepted: 5629 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been

Codeforces Round #629 (Div. 3) F - Make k Equal (离散化 树状数组维护前缀和)

https://codeforces.com/contest/1328/problem/F 首先把a数组处理成pair对(num,cnt),表示数字num有cnt个,然后按num升序排序离散化一下. 对于一个数x,若想使得小于x的数字都变成x,必须先把所有小于x的数变成x-1,然后再+1变成x. 同理,要使得大于x的数变成x,必须把所有大于x的数字变成x+1,然后再-1变成x. 以上是题意所要求的必须操作. 思路: 1. 用f[i]数组记录离散化后前i大的数字的总数,那么对于任意第i大数字,可以

HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gcd种类不超过loga[i]种). 预处理gcd如下代码,感觉真的有点巧妙... 1 for(int i = 1; i <= n; ++i) { 2 int x = a[i], y = i; 3 for(int j = 0; j < ans[i - 1].size(); ++j) { 4 int g

hdu 1541/poj 2352:Stars(树状数组,经典题)

Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4052    Accepted Submission(s): 1592 Problem Description Astronomers often examine star maps where stars are represented by points on a plan

洛谷 P3368 【模板】树状数组 2 如题(区间修改+单点查询)

P3368 [模板]树状数组 2 时空限制1s / 128MB 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含2或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x 含义:输出

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains 【树状数组维护区间最大值】

题目传送门:http://codeforces.com/contest/799/problem/C C. Fountains time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. The

Codeforces1076E. Vasya and a Tree(dfs+离线+树状数组维护)

题目链接:传送门 题目: E. Vasya and a Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Vasya has a tree consisting of n vertices with root in vertex 1. At first all vertices has 0 written on it.

树状数组维护前缀和

树状数组是用来维护序列前缀和的数据结构.它的修改与求和都是O(logn)的,效率非常高. 我们设序列为A,则树状数组c中,c[i]记录序列A的区间[ i-lowbit(i)+1 , i ]中所有数的和. (树状数组是个好东西ovo)  树状数组在进行区间操作时,要从上到下访问,进行单点操作时,要从下到上访问.  树状数组维护序列前缀和的模版如下: #include <iostream> #include <cstdio> #define maxn 500005 using name