题目链接:http://codeforces.com/problemset/problem/652/D
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.
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.
Print n lines. The j-th of them should contain the only integer aj — the number of segments contained in the j-th segment.
4 1 8 2 3 4 7 5 6
3 0 1 0
3 3 4 1 5 2 6
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;
}