Educational Codeforces Round 10 D. Nested Segments 【树状数组区间更新 + 离散化 + stl】
任意门:http://codeforces.com/contest/652/problem/D
D. Nested Segments
2 seconds
256 megabytes
standard input
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.
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
题意概括:
有 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】的更多相关文章
- Educational Codeforces Round 10 D. Nested Segments (树状数组)
题目链接:http://codeforces.com/problemset/problem/652/D 给你n个不同的区间,L或者R不会出现相同的数字,问你每一个区间包含多少个区间. 我是先把每个区间 ...
- Educational Codeforces Round 10 D. Nested Segments 离线树状数组 离散化
D. Nested Segments 题目连接: http://www.codeforces.com/contest/652/problem/D Description You are given n ...
- CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组
题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点 ...
- Educational Codeforces Round 10 D. Nested Segments
D. Nested Segments time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- 【poj2155】Matrix(二维树状数组区间更新+单点查询)
Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...
- 牛客网 暑期ACM多校训练营(第二场)J.farm-STL(vector)+二维树状数组区间更新、单点查询 or 大暴力?
开心.jpg J.farm 先解释一下题意,题意就是一个n*m的矩形区域,每个点代表一个植物,然后不同的植物对应不同的适合的肥料k,如果植物被撒上不适合的肥料就会死掉.然后题目将每个点适合的肥料种类( ...
- 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 ...
- Codeforces Round #261 (Div. 2) D 树状数组应用
看着题意:[1,i]中等于a[i]的个数要大于[,jn]中等于a[j]的个数 且i<j,求有多少对这种(i,j) ,i<j可是 i前面的合法个数 要大于j后面的 看起来非常像逆序数的样子 ...
- NBOJv2 1050 Just Go(线段树/树状数组区间更新单点查询)
Problem 1050: Just Go Time Limits: 3000 MS Memory Limits: 65536 KB 64-bit interger IO format: % ...
随机推荐
- Beam编程系列之Java SDK Quickstart(官网的推荐步骤)
不多说,直接上干货! https://beam.apache.org/get-started/beam-overview/ https://beam.apache.org/get-started/qu ...
- mongodb常用语句(集合操作)
mongodb常用语句(集合操作) 查看集合帮助 db.songs.help(); 查看集合总数据量 db.songs.count(); 查看表空间大小 db.songs.dataSize(); 查看 ...
- pat02-线性结构1. Reversing Linked List (25)
02-线性结构1. Reversing Linked List (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, ...
- 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新
前言 上一章节,简单介绍了分布式配置中心Spring Cloud Config的使用.同时,我们也遗漏了一些问题,比如如何配置实时生效,当服务端地址变更或者集群部署时,如何指定服务端地址?回想,在服务 ...
- bzoj 5303: [Haoi2018]反色游戏
Description Solution 对于一个有偶数个黑点的连通块,只需要任意两两配对,并把配对点上的任一条路径取反,就可以变成全白了 如果存在奇数个黑点的连通块显然无解,判掉就可以了 如果有解, ...
- Android活动的启动模式
1. standard 标准模式,是活动默认的启动模式,在不进行显示指定的情况下,所有活动都会自动使用这种模式. Android使用返回栈管理活动,在standard模式下,每当启动一个新的活动,它就 ...
- js之变量介绍
变量提升 JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部: 'use strict'; function foo() { var x = 'He ...
- SQLAlchemy的使用---增删改查
#通过SQLAlchemy对数据库进行增删改查 # 想要操作数据库 先要打开数据库连接 from create_table import engine # 创建会话 - 打开数据库连接 from sq ...
- 洛谷P1730 最小密度路径(floyd)
题意 题目链接 Sol zz floyd. 很显然的一个dp方程\(f[i][j][k][l]\)表示从\(i\)到\(j\)经过了\(k\)条边的最小权值 可以证明最优路径的长度一定\(\leqsl ...
- JS自定义手机端H5键盘
在输入车牌号的时候,因为很多车牌号都是数字字母混合排列的,所以如果用输入法输入就需要频繁切换数字跟字母,有点麻烦. 在这里我们就用自定义一个弹出框代替键盘来使用. 1.首先,要禁止掉文本框弹出输入法, ...