您的位置:首页 > 其它

[线段树练习5] 线段的条数 - 统计点重复标记数

2017-02-05 23:39 681 查看

题目描述

X轴上从下向上依次叠放一定长度某种颜色的线段。问在某个单位区间上一共叠放了多少条线段?

输入格式

第1行:2个整数XC,N。XC表示X轴的颜色,1<=N<=100000,表示线段的条数。

接下来N行,每行3个整数L,R,C,-100000 <=L<=R<= 100000,表示一线段的左、右端点;1<=C<=100000,表示线段的颜色。

最后1行:1个整数P,表示单位区间的起点。-100000 <=P<100000

输出格式

第1行:1个整数M,表示[P, P+1]区间叠放了多少条线段。

样例数据

样例输入

1 4

2 6 2

1 5 3

3 4 2

7 8 4

3

样例输出

3

题目分析

相对于前几道题,这道题就水了。

区间修改 单点查询

直接统计就可以了

注意偏移量

源代码

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
const int maxn=600000;
struct Tree { //修改区间 查询点
int left,right,sum;
};
struct Segment_Tree { //统计标记次数(颜色有用么)
Tree tree[maxn*4];
int sum;
void build(int index,int Left,int Right) {
tree[index].left=Left;
tree[index].right=Right;
tree[index].sum=0;
if(Left==Right)return;
int mid=(Left+Right)/2;
build(2*index,Left,mid);
build(2*index+1,mid+1,Right);
}
void modify(int index,int Left,int Right) {
if(Right<tree[index].left||Left>tree[index].right)return; //不相交
if(Left<=tree[index].left&&Right>=tree[index].right) { //完全包含
tree[index].sum++;
return;
}
modify(index*2,Left,Right);
modify(index*2+1,Left,Right);
}
void init() {
sum=0;
}
void Query(int index,int target) {
if(target<tree[index].left||target>tree[index].right)return; //不相交
sum+=tree[index].sum;
Query(index*2,target);
Query(index*2+1,target);
}
};
Segment_Tree st;
int n,Delta=100001,color;
int main() {
color=Get_Int();
st.build(1,1,200001);
n=Get_Int();
for(int i=1; i<=n; i++) {
int l=Get_Int()+Delta,r=Get_Int()+Delta-1,color=Get_Int();
st.modify(1,l,r);
}
st.init();
st.Query(1,Get_Int()+Delta);
printf("%d\n",st.sum);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  oi 信息学 线段树
相关文章推荐