线段树练习题四
题目
在平面内有一条长度为n的线段(不计入答案),可以对进行以下2种操作:
1、把从x到y的再加一条线段
2、查询从x到x+1有多少条线段
输入
第一行输入n,m
第2~m+1行,每行2个数x,y,表示从x到y再加一条线段
最后一行输入2个数,为x和x+1,查询x到x+1的线段数目
输出
输出x到x+1的线段数目
输入样例
7 2
2 5
3 6
4 5
输出样例
2
数据范围
100%满足1≤n≤100000,1≤x≤y≤n
解题思路
其实这道题就是一道线段树(emmm…看题目就知道了 ),其实就是先建好一棵树后,然后统计每个区间有多少线即可.
程序如下
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,x,y,xx,yy;
struct r
{
int l,r,sum;
}tree[400001];
void Build(int x,int l,int r)//建树
{
tree[x].l = l;
tree[x].r = r;
if(l + 1 >= r) return ;
int mid = (l + r) / 2;
Build(x * 2,l,mid);
Build(x * 2 + 1,mid,r);
}
void insert(int x,int l,int r)//插入所在区间
{
int mid = (tree[x].l + tree[x].r) / 2;
if(tree[x].l == l && tree[x].r == r)
tree[x].sum++;
else if(r <= mid) insert(x * 2,l,r);
else if(l >= mid) insert(x * 2 + 1,l,r);
else
{
insert(x * 2,l,mid);
insert(x * 2 + 1,mid,r);
}
}
int tj(int x,int l,int r)//统计
{
int ans = tree[1].sum;
while(tree[x].l + 1 < tree[x].r)
{
int mid = (tree[x].l + tree[x].r) / 2;
if(tree[x].l == l && tree[x].r == r) break;
else if(r <= mid)
{
x *= 2;
ans += tree[x].sum;
}
else if(l >= mid)
{
x *= 2;
x++;
ans += tree[x].sum;
}
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
Build(1,1,n);
for(int i = 1;i <= m; ++i)
{
scanf("%d%d",&x,&y);
insert(1,x,y);
}
scanf("%d%d",&xx,&yy);
printf("%d",tj(1,xx,yy));
return 0;
}
本文介绍了一道线段树练习题,涉及在线段上进行增加操作和查询区间线段数量的问题。题目要求在给定的线段上进行增加线段的操作,并能查询特定区间的线段数目。数据范围限制为1≤n≤100000,1≤x≤y≤n。解题思路是利用线段树的数据结构,预先构建并更新线段树,然后快速查询指定区间的线段数量。"
103479452,9167530,机器学习入门:假设函数、代价函数与目标函数解析,"['机器学习', '模型训练', '算法', '预测模型', '数据科学']
1044

被折叠的 条评论
为什么被折叠?



