Happy King

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 821    Accepted Submission(s): 179

Problem Description
There are n cities and n−1 roads in Byteland, and they form a tree. The cities are numbered 1 through n. The population in i-th city is pi.

Soda, the king of Byteland, wants to travel from a city u to another city v along the shortest path. Soda would be happy if the difference between the maximum and minimum population among the cities passed is **no larger than** D. So, your task is to tell Soda how many different pairs (u,v) that can make him happy.

 
Input
There are multiple test cases. The first line of input contains an integer T (1≤T≤500), indicating the number of test cases. For each test case:

The first line contains two integers n and D (1≤n≤100000,1≤D≤109).

The second line contains n integers p1,p2,…,pn (0≤pi≤109).

Each of the following n−1 lines describing roads contains two integers u,v (1≤u,v≤n,u≠v) meaning that there is a road connecting city u and city v.

It is guaranteed that the total number of vertices in the input doesn't exceed 5×105.

 
Output
For each test case, output the number of different pairs that can make Soda happy.
 
Sample Input
1
3 3
1 2 3
1 2
2 3
 
Sample Output
6
/*
hdu 5314 动态树 problem:
给你一个树,求有多少对(u,v)使u->v路径上面的最大值减去最小值不大于limit solve:
最开始想的是用树链剖分维护最大最小值,结果超时 卒。。
然后看别人说动态树比树链剖分快一点,于是去学习两天动态树,然后用其维护最大最小值 卒。。 感觉没什么思路 - -
后来发现别人维护一个树的size.维持树中的最大最小值的差不大于limit
所以先按照权值排序,用两个指针. 如果 当前值-最左边值(l) > limit,就将l从这个树中除去
然后将当前节点连接到树上面,即判断与其相连的点哪些在树上面(可以用个数组来判断). 大致思路如此,然后就是如何维护size. 首先动态树中的重链是一直变化的,通常我们是用splay来维护重链上面的值,
所以需要outsize来维护哪些不在重链上面的点.
而 重链 和 普通链会在ACCESS的时候发生变化,于是在其过程中维护一下. 参考:http://blog.csdn.net/u013368721/article/details/47086899
hhh-2016-08-21 09:16:05
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#define lson ch[0]
#define rson ch[1]
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define key_val ch[ch[root][1]][0]
using namespace std;
const int maxn = 300100;
const int INF = 1e9+10;
ll ans ;
struct Node* null;
struct Node
{
Node* ch[2] ;
Node* fa;
int Size ;
int Outsize;
int val,rev;
void newnode(int v)
{
val = v;
Size = 1 ;
Outsize = 0;
fa = ch[0] = ch[1] = null ;
rev = 0;
}
void update_rev()
{
if(this == null)
return ;
swap(ch[0],ch[1]);
rev ^= 1;
}
void push_up () {
if(this == null)
return ;
Size = ch[0]->Size + 1 + ch[1]->Size + ch[0]->Outsize + ch[1]->Outsize;
// cout << ch[0]->Size <<" " <<ch[1] <<Size <<endl;
} void push_down()
{
if(this == null)
return ;
if(rev)
{
ch[0]->update_rev();
ch[1]->update_rev();
rev = 0;
}
} void link_child ( Node* to , int d )
{
ch[d] = to;
to->fa = this ;
} int isroot()
{
return fa == null || this != fa->ch[0] && this != fa->ch[1] ;
}
void down()
{
if ( !isroot () ) fa->down () ;
push_down () ;
}
void Rotate ( int d )
{
Node* f = fa ;
Node* ff = fa->fa ;
f->link_child ( ch[d] , !d ) ;
if ( !f->isroot () )
{
if ( ff->ch[0] == f ) ff->link_child ( this , 0 ) ;
else ff->link_child ( this , 1 ) ;
}
else fa = ff ;
link_child (f,d) ;
f->push_up () ;
} void splay ()
{
down () ;
while ( !isroot () ) {
if ( fa->isroot () ) {
this == fa->ch[0] ? Rotate ( 1 ) : Rotate ( 0 ) ;
} else {
if ( fa == fa->fa->ch[0] ) {
this == fa->ch[0] ? fa->Rotate ( 1 ) : Rotate ( 0 ) ;
Rotate ( 1 ) ;
} else {
this == fa->ch[1] ? fa->Rotate ( 0 ) : Rotate ( 1 ) ;
Rotate ( 0 ) ;
}
}
}
push_up () ;
} void access()
{
Node* now = this ;
Node* x = null ;
while ( now != null )
{
// cout <<"now:"<< now->val <<" f:" <<x->val <<endl;
now->splay () ;
now->Outsize += (now->ch[1]->Size+now->ch[1]->Outsize);
now->Outsize -= (x->Size + x->Outsize);
now->link_child ( x , 1 );
now->push_up () ;
x = now ;
now = now->fa ;
}
splay() ;
} void make_root()
{
access();
update_rev();
} void cut()
{
access();
ch[0]->fa = null;
ch[0] = null;
push_up();
}
void cut(Node* to)
{
make_root();
to->cut();
} void link(Node* to)
{
make_root();
to->make_root();
fa = to;
// cout << Size <<" " << Outsize <<endl;
ans += (ll)(to->Size + to->Outsize)*(Size+Outsize);
// cout << ans <<endl;
to->Outsize += (Size + Outsize);
push_up();
}
};
Node memory_pool[maxn];
Node* now;
Node* node[maxn];
struct Edge
{
int to,next;
}edge[maxn << 2];
int head[maxn],tot;
int vis[maxn];
void Clear()
{
now = memory_pool;
now->newnode(-INF);
null = now ++;
null->Size = 0;
tot = 0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
} void add_edge(int u,int v)
{
edge[tot].to = v,edge[tot].next = head[u],head[u] = tot ++;
}
struct Point
{
int id,v;
}po[maxn]; bool cmp(Point a,Point b)
{
return a.v < b.v;
}
int main()
{
int T,n,cas = 1,limit;
int x,a,b; // freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
Clear();
scanf("%d%d",&n,&limit);
ans = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d",&x);
now->newnode(x);
node[i] = now++;
po[i].v = x,po[i].id = i;
}
sort(po+1,po+1+n,cmp);
for(int i = 1; i < n; i++)
{
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a);
}
int l= 1;
for(int i =1;i <= n;i++)
{
while(l <= i && po[i].v - po[l].v > limit)
{
int u = po[l].id;
for(int j = head[u];~j;j = edge[j].next)
{
int v = edge[j].to;
if(!vis[v])
continue;
node[u]->cut(node[v]);
}
vis[u] = 0;
++l;
}
int u = po[i].id;
for(int j = head[u];~j; j = edge[j].next)
{
// cout <<edge[j].to <<endl;
int v = edge[j].to;
if(!vis[v])
continue;
node[u]->link(node[v]);
}
vis[u] = 1;
}
printf("%I64d\n",ans*2);
}
return 0;
}

  

hdu 5314 动态树的更多相关文章

  1. hdu 5398 动态树LCT

    GCD Tree Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  2. hdu 5002 (动态树lct)

    Tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  3. hdu 4010 动态树 @

    kuangbin模板题,看起来十分高大上 /* *********************************************** Author :kuangbin Created Tim ...

  4. HDU 2475 BOX 动态树 Link-Cut Tree

    Box Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Problem De ...

  5. HDU 4010 Query on The Trees (动态树)(Link-Cut-Tree)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意; 先给你一棵树,有 \(4\) 种操作: 1.如果 \(x\) 和 \(y\) 不在同一 ...

  6. HDU 4836 The Query on the Tree lca || 欧拉序列 || 动态树

    lca的做法还是非常明显的.简单粗暴, 只是不是正解.假设树是长链就会跪,直接变成O(n).. 最后跑的也挺快,出题人还是挺阳光的.. 动态树的解法也是听别人说能ac的.预计就是放在splay上剖分一 ...

  7. HDU 4718 The LCIS on the Tree (动态树LCT)

    The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Oth ...

  8. 动态树LCT小结

    最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...

  9. 如何利用FineReport制作动态树报表

    在对数据字段进行分类管理时,利用动态树折叠数据是一个很好的方法,也就是点击数据前面的加号才展开对应下面的数据,如下图.那这样的效果在制作报表时该如何实现呢? 下面以报表工具FineReport为例介绍 ...

随机推荐

  1. 冲刺NO.1

    Alpha冲刺第一天 站立式会议 项目进展 项目的第一天,主要工作是对项目的开发进行规划,以及将规划的成果转化为燃尽图与博客文章.依据项目需求分析报告与开题报告中已经完成的设计任务和项目规划,我们将系 ...

  2. C语言--第四周作业

    一.题目7-1 计算分段函数[1] 1.代码 #include <stdio.h> int main () { float x,result; scanf("%f",& ...

  3. HTTP协议以及HTTP2.0/1.1/1.0区别

    HTTP协议以及HTTP2.0/1.1/1.0区别 一.简介 摘自百度百科: 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所 ...

  4. Java可重入锁如何避免死锁

    本文由https://bbs.csdn.net/topics/390939500和https://zhidao.baidu.com/question/1946051090515119908.html启 ...

  5. JAVA_SE基础——47.接口

    如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另一种方法来定义,即接口~ 在定义接口时,需要用interface关键字来声明,具体实例如code1 接口的定义格式:interface 接口名{ ...

  6. Python之旅_计算机基础入门

    一.计算机基础 1.Python是编程语言 语言:一种事物与另一种事物沟通的介质. 编程语言:程序员与计算机沟通的介质. 什么是编程:程序员用编程语言把自己的逻辑思想下来,编程的结果就是一堆文件. 为 ...

  7. volt问题

    1./表示当前目录:/college/detail/{{ item.sid }}表示这个路径超链接,url实在不好写就不写,作为开发人员想怎么弄就怎么弄最后发布是项目主管的事 2.不需要服务器给值,直 ...

  8. C++ 异常小记

    catch必定使用拷贝构造函数 如下代码编译不通过,因为拷贝构造被标记delete #include <stdexcept> #include <cstdlib> #inclu ...

  9. C#中DBNull.Value和Null的用法和区别

    DBNull.Value,, 是适用于向数据库的表中插入空值.而 null,是指在程序中表示空引用. 或者对象为空.就是没有实例化. row[column]的值为DBNull.Value的话,至少说明 ...

  10. 常用cmd代码片段及.net core打包脚本分享

    bat基础命令 注释:rem 注释~~ 输出:echo hello world 接收用户输入:%1 %2,第n个变量就用%n表示 当前脚本路径:%~dp0 当前目录路径:%cd% 设置变量:set c ...