They say that Berland has exactly two problems, fools and roads. Besides, Berland has n cities, populated by the fools and connected by the roads. All Berland roads are bidirectional. As there are many fools in Berland, between each pair of cities there is a path (or else the fools would get upset). Also, between each pair of cities there is no more than one simple path (or else the fools would get lost).

But that is not the end of Berland's special features. In this country fools sometimes visit each other and thus spoil the roads. The fools aren't very smart, so they always use only the simple paths.

A simple path is the path which goes through every Berland city not more than once.

The Berland government knows the paths which the fools use. Help the government count for each road, how many distinct fools can go on it.

Note how the fools' paths are given in the input.

Input

The first line contains a single integer n (2 ≤ n ≤ 105) — the number of cities.

Each of the next n - 1 lines contains two space-separated integers ui, vi (1 ≤ ui, vi ≤ nui ≠ vi), that means that there is a road connecting cities ui and vi.

The next line contains integer k (0 ≤ k ≤ 105) — the number of pairs of fools who visit each other.

Next k lines contain two space-separated numbers. The i-th line (i > 0) contains numbers ai, bi (1 ≤ ai, bi ≤ n). That means that the fool number 2i - 1 lives in city ai and visits the fool number 2i, who lives in city bi. The given pairs describe simple paths, because between every pair of cities there is only one simple path.

Output

Print n - 1 integer. The integers should be separated by spaces. The i-th number should equal the number of fools who can go on the i-th road. The roads are numbered starting from one in the order, in which they occur in the input.

Sample test(s)
input
5
1 2
1 3
2 4
2 5
2
1 4
3 5
output
2 1 1 1 
input
5
3 4
4 5
1 4
2 4
3
2 3
1 3
3 5
output
3 1 1 1 
Note

In the first sample the fool number one goes on the first and third road and the fool number 3 goes on the second, first and fourth ones.

In the second sample, the fools number 1, 3 and 5 go on the first road, the fool number 5 will go on the second road, on the third road goes the fool number 3, and on the fourth one goes fool number 1.

给出一棵树,树有边权,边权初始都为0,给出k个操作,每一个操作给出u v

表示u,v路径上的所有边权都加1

所有操作完后,按照边输入的顺序输出每一条边的边权

一看,树链剖分裸题

但是想想,其实是可以不用树链剖分做的

可以用lca

我们令root=1

dis[i]表示节点i到root的距离

对于每一个操作u v,相当于

dis[u]++

dis[v]++

dis[lca(u,v)]-=2

所有操作完后,我们再一次dfs(root),自底向上累加所有dis,就可以了

dis[u]+=dis[son(u)]

然后按照输入的顺序输出边权就好啦

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<map>
#include<set> #define LL long lon
#define pb push_back using namespace std; const int inf=0x3f3f3f3f;
const int maxn=1e5+; int dis[maxn];
int dep[maxn];
int dp[maxn][];
int e[maxn][]; struct Edge
{
int to,next;
};
Edge edge[maxn<<];
int head[maxn];
int tot; void init_edge()
{
memset(head,-,sizeof head);
tot=;
} void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
} void solve(int ); int main()
{
init_edge();
int n;
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d %d",&e[i][],&e[i][]);
addedge(e[i][],e[i][]);
addedge(e[i][],e[i][]);
}
solve(n); return ;
} void dfs0(int u,int pre)
{
dep[u]=dep[pre]+;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==pre)
continue;
dp[v][]=u;
dfs0(v,u);
}
} void init_dp(int n)
{
for(int j=;(<<j)<=n;j++){
for(int i=;i<=n;i++){
if(dp[i][j-]!=-)
dp[i][j]=dp[dp[i][j-]][j-];
}
}
} int query_lca(int a,int b)
{
if(dep[a]<dep[b])
swap(a,b);
int cnt;
for(cnt=;(<<cnt)<=dep[a];cnt++)
;
cnt--;
for(int j=cnt;j>=;j--){
if(dep[a]-(<<j)>=dep[b])
a=dp[a][j];
}
if(a==b)
return a;
for(int j=cnt;j>=;j--){
if(dp[a][j]!=- && dp[a][j]!=dp[b][j]){
a=dp[a][j];
b=dp[b][j];
}
}
return dp[a][];
} void dfs1(int u)
{
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==dp[u][])
continue;
dfs1(v);
dis[u]+=dis[v];
}
} void solve(int n)
{
memset(dp,-,sizeof dp);
memset(dep,,sizeof dep);
memset(dis,,sizeof dis);
dfs0(,);
init_dp(n);
int q;
scanf("%d",&q);
for(int i=;i<=q;i++){
int u,v;
scanf("%d %d",&u,&v);
dis[u]++;
dis[v]++;
dis[query_lca(u,v)]-=;
}
dfs1(); for(int i=;i<n;i++){
int cur=e[i][];
if(dep[e[i][]]<dep[e[i][]])
cur=e[i][];
printf("%d",dis[cur]);
i==n-?puts(""):printf(" ");
}
return ;
}

CF 191C Fools and Roads lca 或者 树链剖分的更多相关文章

  1. [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]

    参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...

  2. 【BZOJ3626】LCA(树链剖分,Link-Cut Tree)

    [BZOJ3626]LCA(树链剖分,Link-Cut Tree) 题面 Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. ...

  3. uva 12655 Trucks [LCA](树链剖分+MST)

    The Subtle Balloons Company (SBC) is the main balloon provider for programming contests; it hashuge ...

  4. LCA 倍增||树链剖分

    方法1:倍增 1498ms #include <iostream> #include <cstdio> #include <algorithm> #include ...

  5. 从lca到树链剖分 bestcoder round#45 1003

    bestcoder round#45 1003 题,给定两个点,要我们求这两个点的树上路径所经过的点的权值是否出现过奇数次.如果是一般人,那么就是用lca求树上路径,然后判断是否出现过奇数次(用异或) ...

  6. P3379 【模板】最近公共祖先(LCA)(树链剖分)版

    #include <bits/stdc++.h> #define read read() #define up(i,l,r) for(register int i = (l);i < ...

  7. 2018.09.16 bzoj3626: [LNOI2014]LCA(树链剖分)

    传送门 树链剖分好题. 对于每个点维护一个值vi" role="presentation" style="position: relative;"&g ...

  8. BZOJ 3626 LCA(离线+树链剖分)

    首先注意到这样一个事实. 树上两个点(u,v)的LCA的深度,可以转化为先将u到根路径点权都加1,然后求v到根路径上的总点权值. 并且该题支持离线.那么我们可以把一个区间询问拆成两个前缀和形式的询问. ...

  9. JZYZOJ1454 NOIP2015 D2T3_运输计划 二分 差分数组 lca tarjan 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1454 从这道题我充分认识到我的脑子里好多水orz. 如果知道了这个要用二分和差分写,就没什么思考上的难点了(屁咧你写了一 ...

随机推荐

  1. 1-3 ISO/OSI七层模型详解

    一.物理层 1.负责设备之间的比特流的传输.物理接口.电气特性等. <1>物理接口:网线接口型号.音频线接口型号.视频线接口型号等 <2>电气特性:例如网线总共8根线,这8根线 ...

  2. UVA-11468 Substring(AC自动机+DP)

    题目大意:给一些模板串,一些字符的出现概率.问不会出现模板串的概率是多少. 题目分析:是比较简单的概率DP+AC自动机.利用全概率公式递推即可. 代码如下: # include<iostream ...

  3. Java中相等测试

    一:equals与==的区别 (1)基本数据类型 byte,short,char,int,long,float,double,boolean 此类数据类型的比较需要使用==,此时比较的是他们的值,若相 ...

  4. Python正则表达式总结

    正则表达式也一直用,但是没系统的总结过,今天借这个时间梳理一下. Python中的正则表达式操作依靠re模块儿完成. 常用的方法: re.compile(pattern,flags=0) #返回一个编 ...

  5. java多线程之:线程对象一些api

    一:wait()方法,wait(long timeout)--->锁对象调用wait()方法,让当前线程小a进入等待状态,阻塞住,并让出当先线程拥有的锁.--->直到其他线程用锁对象调用n ...

  6. Learn python the hard way. python test program 2016.04.27

    # this will not be printed in python ! print "I could have code like this." # and the comm ...

  7. kmeans算法

    # coding:utf-8 import numpy as np import matplotlib.pyplot as plt def dis(x, y): #计算距离 return np.sum ...

  8. python--web.py使用

    web.py 是一个轻量级Python web框架. 下面我将使用web.py框架,创建一个简单的html页面示例. 1.项目的目录结构如下所示: exweb2\  uniqueenv\  app.p ...

  9. IPy

    IPy生成网段列表from IPy import IPip = IP('192.168.0.0/16')print ip.len()for x in ip:print (x) ip的属性,'PUBLI ...

  10. 把excel数据生成sql insert语句

    excel表格中有A.B.C三列数据,希望导入到数据库users表中,对应的字段分别是name,sex,age . 在你的excel表格中增加一列,利用excel的公式自动生成sql语句,方法如下: ...