传送门

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. mysqldump: Got error: 1142: SELECT, LOCK TABLES command denied to user 'root'@'localhost' for table 'accounts' when using LOCK TABLES

    AutoMySQLBackup备份时,出现mysqldump: Got error: 1142: SELECT, LOCK TABLES command denied to user 'root'@' ...

  2. MS SQL 日常维护管理常用脚本(二)

    监控数据库运行 下面是整理.收集监控数据库运行的一些常用脚本,也是MS SQL 日常维护管理常用脚本(一)的续集,欢迎大家补充.提意见. 查看数据库登录名信息   Code Snippet SELEC ...

  3. mysql 单表排序,相同值排序

    两种方式: 第一种是利用笛卡尔积,两对比排序 -- 学校类型数据 SELECT t.examid,'-' AS unitcode,t.schooltype,'-' AS classname,t.bkr ...

  4. mvc页面跳转

    用例列举: RedirectToAction: return RedirectToAction("PublicPreview", controllerName, new { id ...

  5. chrome 浏览器的预提取资源机制导致的一个请求发送两次的问题以及ClientAbortException异常

    调查一个 pdf 打印报错: ExceptionConverter: org.apache.catalina.connector.ClientAbortException: java.net.Sock ...

  6. [Java入门笔记] 面向对象编程基础(三):成员变量和局部变量

    在类中,变量根据定义的位置不同,可以分为成员变量和局部变量.

  7. 关于oracle中数据类型的选择

    由于是初学,犯了如下错误: 生成表的主键id时,用当前时间的毫秒值.而在oracle中定义主键id时,用的数据类型是char(32).在mybatis中通过id取数据怎么也取不出来.想了好几天,本来以 ...

  8. JavaScript中function的多义性

    JavaScript 中的 function 有多重意义.它可能是一个构造器(constructor),承担起对象模板的作用: 可能是对象的方法(method),负责向对象发送消息.还可能是函数,没错 ...

  9. 【Windows编程】系列第二篇:Windows SDK创建基本控件

    在Win32 SDK环境下,怎么来创建常用的那些基本控件呢?我们知道如果用MFC,简单的拖放即可完成大多数控件的创建,但是我们既然是用Windows SDK API编程,当然是从根上解决这个问题,实际 ...

  10. C#性能优化考虑的几个方向

    装箱与拆箱 ArrayList's vs. generic List for primitive types and 64-bits 类型转换   GC 注意SOH对象应该较快,避免内存泄漏 注意LO ...