传送门

Problem Statement

You are given a tree where each node is labeled from 1 to n. How many similar pairs(S) are there in this tree?

A pair (A,B) is a similar pair if the following are true:

  • node A is the ancestor of node B
  • abs(A−B)≤T

Input format: 
The first line of the input contains two integers, n and T. This is followed by n−1 lines, each containing two integers si and ei where node si is a parent to node ei.

Output format: 
Output a single integer which denotes the number of similar pairs in the tree.

Constraints: 
1≤n≤100000 
0≤T≤n 
1≤si, ei ≤n

Sample Input:

5 2
3 2
3 1
1 4
1 5

Sample Output:

4

Explanation: 
The similar pairs are: (3, 2) (3, 1) (3, 4) (3, 5).

You can have a look at the tree image here

-------------------------------------------------------------
Solution:
题目给出一棵有根树,要求统计其中满足以下条件的点对(A, B)的数目
(1) A是B的祖先(但A不能等于B,即A应是B的合法(proper)祖先)
(2)abs(A-B)<=T(即两点编号之差的绝对值应不大于T)
--------------------------------------------------------
解法不难想,类似于树形DP,DFS遍历这棵有根树,以后序(或者说后序遍历)将各个顶点的编号逐一放到集合中。在进入以顶点u为根的子树时,先查询当前集合中有多少节点v满足 abs(v-u)<=T,遍历完这棵子树后在查询一次,由于新添进集合的都是u的后代,所以两次结果相减便是符合条件的点对(u,x)的数目。对每个节点都做类似的查询结果加起来就是答案。
--------------------------------------------------------------
至此,问题归结为如何维护这个集合,显然树状数组(BIT)是最合适的
#include <bits/stdc++.h>
using namespace std;
int T, n;
const int N(1e5+);
int bit[N];
int sum(int x){
int s=;
while(x){
s+=bit[x];
x-=x&-x;
}
return s; //error-prone
}
void add(int x){
while(x<=n){
bit[x]++;
x+=x&-x;
}
}
int get_ans(int x){
int l=max(x-T-, );
int r=min(n, x+T);
return sum(r)-sum(l);
}
int par[N];
vector<int> g[N];
long long ans;
void dfs(int u){
int tmp=get_ans(u);
for(int i=; i<g[u].size(); i++){
int &v=g[u][i];
dfs(v);
}
ans+=get_ans(u)-tmp;
add(u);
}
int main(){
//freopen("in", "r", stdin);
cin>>n>>T;
for(int i=, u, v; i<n; i++){
cin>>u>>v;
par[v]=u;
g[u].push_back(v);
}
int root=;
while(par[root])
root=par[root];
dfs(root);
cout<<ans<<endl;
}

--------------------------------------------

我们在考虑能否用C++ STL中的 set实现这个集合

显然我们需要支持3种操作

1. 插入,set OK

2.查询集合中大于x的数有多少个

3.查询集合中小于x的数有多少个

下面的资料摘自C++ Primer (5th. edition)

P. 330

Table 9.2 Contianer Operations

Type Aliases

difference_type Signed integral type big enough to hold the distance between two iterators

------------------------------------------------------------------------------------------------------------
我们知道set和map都支持upper_bound(),lower_bound(),可尝试用这两个函数来实现上述后两个查询。
比如我们想查询集合s中在[L, R]范围内的数有多少个,试着写成
set<int> s;
int f(int l, int r){
return s.upper_bound(r)-s.lower_bound(l);
}

但这是行不通的,编译时报错:

:no match for ‘operator-’ (operand types are ‘std::set<int>: :iterator {aka std::_Rb_tree_const_iterator<int>}’ and ‘std::set<int>::iterator {aka std::_Rb_tree_const_iterator<int>}’)

因为set<int>::iterator不支持-(减法)

------------------------------------------------

只能写成

set<int> s;
int f(int l, int r){
auto b=s.lower_bound(l), e=s.upper_bound(r);
int res=;
while(b!=e){ //use != rather than <
++b;
++res;
}
return res;
}

但这样写复杂度是O(n),不能承受。

Bjarne Stroustrup TC++PL (4th. edition) P.954

The reason to use != rather than < for testing whether we have reached the end is partially because that is

the more precise statement of what we testing for and partially because only random-access iterators support <.

----------------------------------------------------------

 
 
 

hackerrank Similar Pair的更多相关文章

  1. R语言-混合型数据聚类

    利用聚类分析,我们可以很容易地看清数据集中样本的分布情况.以往介绍聚类分析的文章中通常只介绍如何处理连续型变量,这些文字并没有过多地介绍如何处理混合型数据(如同时包含连续型变量.名义型变量和顺序型变量 ...

  2. 【LeetCode】734. Sentence Similarity 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 只修改区间起终点 日期 题目地址:https://le ...

  3. RFID Exploration and Spoofer a bipolar transistor, a pair of FETs, and a rectifying full-bridge followed by a loading FET

    RFID Exploration Louis Yi, Mary Ruthven, Kevin O'Toole, & Jay Patterson What did you do? We made ...

  4. *[hackerrank]Algorithmic Crush

    https://www.hackerrank.com/contests/w4/challenges/crush 第一眼觉得要用线段树,但据说会超时.其实这个可以通过生成pair排序来做. #inclu ...

  5. 【HackerRank】How Many Substrings?

    https://www.hackerrank.com/challenges/how-many-substrings/problem 题解 似乎是被毒瘤澜澜放弃做T3的一道题(因为ASDFZ有很多人做过 ...

  6. [Functional Programming] mapReduce over Async operations and fanout results in Pair(rejected, resolved) (fanout, flip, mapReduce)

    This post is similar to previous post. The difference is in this post, we are going to see how to ha ...

  7. Code Signal_练习题_Are Similar?

    Two arrays are called similar if one can be obtained from another by swapping at most one pair of el ...

  8. MOSFET pair makes simple SPDT switch

    With an n- and p-channel MOSFET, you can easily implement a single-pole double-throw (SPDT) switch t ...

  9. 2017-5-14 湘潭市赛 Similar Subsequence 分析+四维dp+一些简单优化

    Similar Subsequence Accepted : Submit : Time Limit : MS Memory Limit : KB Similar Subsequence For gi ...

随机推荐

  1. 人工智能与3A

    我在Tid2014上的一个小视频: 下一代的码农会是什么样的呢?且听咕咚老王的“3A”畅谈——“Ai.Art.Any”. 在艺术的视角下,世界是沉寂的.美丽的: 在码农的眼中,世界是有“码”的朦胧美吗 ...

  2. Vmware扩展磁盘如何不需重启系统

    在虚拟机Vmware中我们有时候需要添加新的虚拟磁盘或给已有虚拟磁盘扩容(expand),在新增磁盘或磁盘扩容后,Linux系统并不能马上识别到.也就是说你看不到磁盘空间变化(使用fdisk -l查看 ...

  3. JDK1.3安装出现/lib/ld-linux.so.2: bad ELF interpreter: No such file or directory Done.

    今天是出道以来第一次安装JDK1.3,大学的时候接触的也已是JDK1.4,而且是在Red Hat Enterprise Linux Server release 6.6上,安装JDK1.3是由于软件组 ...

  4. SQLite使用(一)&&选择表类型

    在SQLite中,主要有两种表类型,带rowid的表和不带rowid的表.我们利用create table 建一张表,默认都会有一个隐含名字为rowid的主键,暂且称带rowid的表为普通表.如果建表 ...

  5. Oracle分区表

    先说句题外话-   欢迎成都天府软件园的小伙伴来面基交流经验~ 一:什么是分区(Partition)? 分区是将一个表或索引物理地分解为多个更小.更可管理的部分. 分区对应用透明,即对访问数据库的应用 ...

  6. Linux 命令学习

    当前登陆目录:

  7. android穿越之旅--如何弹出一个非比寻常的窗体

    上一篇中介绍了一种闻所未闻在android执行java命令的方法,虽然这是一种非常"高级"的技术,然后并没有什么卵用,因此被移除了博客园首页.实际上也并不是一点用处也没有,对已立即 ...

  8. CentOS 7 无法使用中文输入法

    已经在安装CentOS时设置了中文输入法,在"设置"-"区域与语言"选项里也可以看到如下图所示的界面,但在文档中切换后无法使用的问题:

  9. FFMPEG在嵌入式硬件上应用之 —— 基本环境搭建及编译

    前段时间在翻看电脑里面资料时,发现了以前做的在嵌入式硬件上面运行以ffmepg为基础,以嵌入式硬件解码的多媒体播放工作,发现都快忘记完了.今日得闲整理温习了一下ffmpeg在嵌入式上的运用,这里给大家 ...

  10. winform/窗体鼠标事件编程中的几个问题

    1.进行.net窗体的开发,经常用到鼠标事件,如MouseDown/MouseUp/MouseMove/MouseClick等.可是有时候给控件添加鼠标事件,就是不响应,怎么办呢! 答案:1.控件是否 ...