任意门:http://codeforces.com/contest/652/problem/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

Copy
4
1 8
2 3
4 7
5 6
output

Copy
3
0
1
0
input

Copy
3
3 4
1 5
2 6
output

Copy
0
1
1

题意概括:

有 N 个区间,求每个区间有多少个存在的子区间。

例如第一个样例:

4
1 8
2 3
4 7
5 6 【1,8】有 3 个,他们发别是 【2,3】,【4,7】,【5,6】;
【2,3】没有;
【4,7】有 1 个,【5,6】;【5,6】没有;

注意:

一、只是有部分相交的区间不在考虑范围内,模拟一下样例二就明白了。

3
3 4
1 5
2 6

二、端点不重合,这个很重要!!!

解题思路:

由题意可知这是离线操作,涉及区间查询和修改,线段树或树状数组。

其次数据范围不小,要考虑离散化。

这道题如何离散化?

二维 pair 储存原数据 + vector 排序&&去重;

树状数组要维护一些什么呢?我们怎么记录区间内有几个符合条件的线段呢?

一开始自己模拟样例一后是想到标记左端点,然后求其区间和,刚好区间和 减去他自己就是答案,不够这种想法是很片面的。

因为有只有部分相交的情况:例如样例二

【1,5】= 1+1+1-1 = 2 答案错误(把部分相交的考虑进去了)

但这道题的解决方法就是标记一个端点,如果标记左端点则按右端点顺序遍历,如果标记右端点则按左端点顺序遍历。

固定其中一个端点后求区间和,并且在查询完毕之后要消除当前区间对后面区间的影响,因为我们按照其中一个端点的顺序遍历,如果不消除当前固定端点区间的影响,那么后面就会有部分相交了。

例如说我标记左端点,按照右端点的顺序遍历,如果我遍历右端点为 6 之后没有把【2, 6】的影响消除,那么当我遍历到右端点为 5 的时候就会把只有部分相交的区间也记录进去了。

解决了以上两个大问题,剩下的就是代码实现的事了。

AC code:

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MAXN = 4e5+; int t[MAXN]; //树状数组
pair< pair<int, int>, int> p[MAXN]; //记录区间左右端点和
vector<int> Q;
map<int, int> mmp;
int ans[MAXN];
int N; int lowbit(int x){return x&(-x);}
void Update(int x, int val)
{
for(int i = x; i < MAXN; i+=lowbit(i)){
t[i]+=val;
}
} int query(int x)
{
int res = ;
for(int i = x; i; i-=lowbit(i))
res+=t[i];
return res;
} int main()
{
scanf("%d", &N);
for(int i = ; i <= N; i++){
scanf("%d %d", &p[i].first.first, &p[i].first.second);
Q.push_back(p[i].first.first);
Q.push_back(p[i].first.second);
p[i].second = i;
}
sort(Q.begin(), Q.end()); //离散化
Q.erase(unique(Q.begin(),Q.end()), Q.end()); //去重
for(int i = ; i < Q.size(); i++){
mmp[Q[i]] = i+; //新旧端点的映射关系
}
for(int i = ; i <= N; i++){
p[i].first.first = mmp[p[i].first.first]; //更新区间的左右端点
p[i].first.second = mmp[p[i].first.second];
Update(p[i].first.second, ); //更新区间!!!精妙之处在于标记的该区间的其中一个端点!!!(题目条件端点不重合)
}
sort(p+, p++N); //排序等级:左端点 > 右端点 > 区间编号
for(int i = , j = ; i < MAXN; i++){ //遍历左端点,注意范围是 1~MAXN
while(j <= N && p[j].first.first == i){ //左端点相同的区间
ans[p[j].second] = query(p[j].first.second);
Update(p[j].first.second, -); //消除当前区间对后面区间的影响
j++;
}
if(j == N+) break; //遍历完成
}
for(int i = ; i <= N; i++)
printf("%d\n", ans[i]-);
return ;
}

Educational Codeforces Round 10 D. Nested Segments 【树状数组区间更新 + 离散化 + stl】的更多相关文章

  1. Educational Codeforces Round 10 D. Nested Segments (树状数组)

    题目链接:http://codeforces.com/problemset/problem/652/D 给你n个不同的区间,L或者R不会出现相同的数字,问你每一个区间包含多少个区间. 我是先把每个区间 ...

  2. Educational Codeforces Round 10 D. Nested Segments 离线树状数组 离散化

    D. Nested Segments 题目连接: http://www.codeforces.com/contest/652/problem/D Description You are given n ...

  3. CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组

    题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点 ...

  4. Educational Codeforces Round 10 D. Nested Segments

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

  5. 【poj2155】Matrix(二维树状数组区间更新+单点查询)

    Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...

  6. 牛客网 暑期ACM多校训练营(第二场)J.farm-STL(vector)+二维树状数组区间更新、单点查询 or 大暴力?

    开心.jpg J.farm 先解释一下题意,题意就是一个n*m的矩形区域,每个点代表一个植物,然后不同的植物对应不同的适合的肥料k,如果植物被撒上不适合的肥料就会死掉.然后题目将每个点适合的肥料种类( ...

  7. Codeforces Round #365 (Div. 2) D 树状数组+离线处理

    D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes in ...

  8. Codeforces Round #261 (Div. 2) D 树状数组应用

    看着题意:[1,i]中等于a[i]的个数要大于[,jn]中等于a[j]的个数 且i<j,求有多少对这种(i,j)  ,i<j可是 i前面的合法个数 要大于j后面的 看起来非常像逆序数的样子 ...

  9. NBOJv2 1050 Just Go(线段树/树状数组区间更新单点查询)

    Problem 1050: Just Go Time Limits:  3000 MS   Memory Limits:  65536 KB 64-bit interger IO format:  % ...

随机推荐

  1. zabbix-proxy 层级制监控

    一,zabbix服务规划 zabbix-server 10.0.0.71 zabbix-proxy 10.0.0.72 172.16.1.72 web01  172.16.1.7 二,zabbix 客 ...

  2. 日志收集之filebeat

    一,软件介绍 Filebeat是一个轻量级日志传输Agent,可以将指定日志转发到Logstash.Elasticsearch.Kafka.Redis等中.Filebeat占用资源少,而且安装配置也比 ...

  3. shell 实现文件改名

    修改文件名可以有不同的命令方式,mv 可以实现,但是使用rename 这种专业的改名字很好 对于单个的文件,可以直接使用以上的命令,那如果有大量的类似格式的文件名需要修改成其他格式的,该如何呢? 创建 ...

  4. (转)source、sh、bash、./执行脚本的区别

    source.sh.bash../执行脚本的区别  原文:https://www.cnblogs.com/sparkbj/p/5976100.html 1.source命令用法: source Fil ...

  5. How to add more to Git Bash on Windows

    How to add more to Git Bash on Windows Download the lastest wget binary for windows from https://ete ...

  6. bzoj 5217: [Lydsy2017省队十连测]航海舰队

    Description Byteasar 组建了一支舰队!他们现在正在海洋上航行着.海洋可以抽象成一张n×m 的网格图,其中有些位置是" .",表示这一格是海水,可以通过:有些位置 ...

  7. 如何用 windows+github搭建一个优美的hexo博客

    1.Hexo简单介绍 Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页. 风一般的速度Hexo基于Nod ...

  8. guava的限流工具RateLimiter使用

    guava限流工具使用 非常详细的一篇使用博客:https://www.cnblogs.com/yeyinfu/p/7316972.html 1,原理:Guava RateLimiter基于令牌桶算法 ...

  9. Mac安装Gradle eclipse安装buildship插件

    一直用的eclipse+mvn,现在需要导入别人的gradle项目,所以下载了gradle和在eclipse中安装了buildship插件. 一,mac下安装gradle 1,点击网页https:// ...

  10. 避免console错误,console兼容

    背景:写js代码时写了很多console.log进行日志打印,最后上生产时不想删除日志输出, 但是ie在不打开控制台时,日志输出会导致后续js不执行,所以需要适时屏蔽js日志输出 (IE等不支持con ...