CodeForces 652D Nested Segments(离散化,树状数组)

本文解析了CodeForces D题“NestedSegments”的解题思路,通过使用树状数组进行离散化处理来解决区间包含问题。介绍了输入输出格式及核心代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://codeforces.com/problemset/problem/652/D

D. Nested Segments
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given n segments on a line. There are no ends of some segments that coincide. For each segment find the number of segments it contains.

Input

The first line contains a single integer n (1 ≤ n ≤ 2·105) — the number of segments on a line.

Each of the next n lines contains two integers li and ri ( - 109 ≤ li < ri ≤ 109) — the coordinates of the left and the right ends of the i-th segment. It is guaranteed that there are no ends of some segments that coincide.

Output

Print n lines. The j-th of them should contain the only integer aj — the number of segments contained in the j-th segment.

Examples
input
4
1 8
2 3
4 7
5 6
output
3
0
1
0
input
3
3 4
1 5
2 6
output
0
1
1

题意:

给定一些序列的开始和结束点,问包含的序列有多少段(词穷了)。怎么描述呢?

测试数据 1,看图——>



思路:

采用树状数组,但是数据范围较大,需要离散化处理。


AC Code :

#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
const int MYDD=1103+2e5;

int Ans[MYDD];
int tree[MYDD];
struct Q {
	int id; /* 标记最初信息 */
	int l,r;
} s[MYDD]; //segments
bool cmp_l(Q x,Q y) {
	return x.l<y.l;
}

bool cmp_r(Q x,Q y) {
	return x.r<y.r;
}

int LowBit(int x) {
	return x&(-x);
}
/* 树状数组模板 */
void UpDate(int x,int value,int n) {
	while(x<=n) {
		tree[x]+=value;
		x+=LowBit(x);
	}
}

int GetSum(int x,int n) {
	int ans=0;
	while(x>0) {
		ans+=tree[x];
		x-=LowBit(x);
	}
	return ans;
}

int main() {
	int n;
	scanf("%d",&n);
	for(int j=1; j<=n; j++) {
		scanf("%d%d",&s[j].l,&s[j].r);
		s[j].id=j;
	}

	sort(s+1,s+1+n,cmp_r);
	for(int j=1; j<=n; j++)
		s[j].r=j;/* 离散化 */

	sort(s+1,s+1+n,cmp_l);
	for(int j=n; j>=1; j--) {/* 更新节点权值 */
		Ans[s[j].id]=GetSum(s[j].r,n);
		UpDate(s[j].r,1,n);
	}

	for(int j=1; j<=n; j++)
		printf("%d\n",Ans[j]);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值