传送门

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. 编写Javascript类库(jQuery版) - 进阶者系列 - 学习者系列文章

    这些年主要关注于项目管理方面的工作,编码就比较少了.这几天比较空闲,就想把原来的经验沉淀下来,一个是做好记录,以后如果忘记了还能尽快找回来,第二个是写写博文,算是练练手笔吧. 言归正传,这次写的是Ja ...

  2. [转载]了解Linux的进程与线程

    本文转自Tim Yang的博客http://timyang.net/linux/linux-process/ .对于理解Linux的进程与线程非常有帮助.支持原创.尊重原创,分享知识! 上周碰到部署在 ...

  3. SQL SERVER 2012 修改数据库默认位置不立即生效

    今天修改SQL SERVER 2012的数据库默认位置:即数据文件.日志文件默认位置时遇到一个问题,单击"服务器属性"(Server Properties)--> 数据库设置 ...

  4. PHP服务缓存优化之ZendOpcache、xcache、eAccelerator

    PHP服务缓存优化原理 Nginx 根据扩展名或者过滤规则将PHP程序请求传递给解析PHP的FCGI,也就是php-fpm进程 缓存操作码(opcode) Opcode,PHP编译后的中间文件,缓存给 ...

  5. .NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上下文环境检查(实战)

    Microsoft.NET 解决方案,项目开发必知必会. 从这篇文章开始我将分享一系列我认为在实际工作中很有必要的一些.NET项目开发的核心技术点,所以我称为必知必会.尽管这一系列是使用.NET/C# ...

  6. [MySQL性能优化系列]LIMIT语句优化

    1. 背景 假设有如下SQL语句: SELECT * FROM table1 LIMIT offset, rows 这是一条典型的LIMIT语句,常见的使用场景是,某些查询返回的内容特别多,而客户端处 ...

  7. 内存管理内幕mallco及free函数实现

    原文:https://www.ibm.com/developerworks/cn/linux/l-memory/ 为什么必须管理内存 内存管理是计算机编程最为基本的领域之一.在很多脚本语言中,您不必担 ...

  8. js输出二维数组最长的子数组

    ,,],[,,,],[,,,,]]; ].length; ; i < a.length; i++) { if (max<a[i].length) { max=a[i].length; va ...

  9. 使用 python 实现 memcached 的启动服务脚本 rc

    #!/usr/bin/python #coding:utf-8 import sys import os from subprocess import Popen, PIPE class Memcac ...

  10. 虚拟机装系统出现 ntldr is missing(NTLDR丢失)、无法正常开机、解决方法

    虚拟机(VMware Workstation或Hyper-V)装ghost版系统提示“ntldr is missing Press Ctrl+Alt+del to Resta 此方法对实体机.虚拟机安 ...