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. 创建kafkatopic和productor

    cd 到kafka 目录下 创建topic create topicbin/kafka-topics.sh --zookeeper spark1:2181,spark2:2181,spark3:218 ...

  2. POJ 3422Kaka's Matrix Travels(最小费用最大流)

                                                            Kaka's Matrix Travels Time Limit: 1000MS   M ...

  3. 软件推荐 - Source Insight

    一直以来从事的开发工作,涉及的范围很杂,乱七八糟的都有,其中有一项占据了比较长的时间,那就是固件程序的开发,不涉及操作系统,也就是一般意义上大家所说的裸跑程序.​用过的芯片杂七杂八,比较主要的有Ate ...

  4. GNU C 扩展(转)

    GNU CC 是一个功能非常强大的跨平台 C 编译器,它对 C 语言提供了很多扩展,这些扩展对优化.目标代码布局.更安全的检查等方面提供了很强的支持.这里对支持支持 GNU 扩展的 C 语言成为 GN ...

  5. Instructions函数对照表:02 xmmintrin.h与SSE指令集[转]

    更多详情见——http://www.cnblogs.com/zyl910/archive/2012/04/26/md00.htmlSIMD函数整理:00 索引贴 R:寄存器.M:64位MM寄存器:X: ...

  6. 关于$.ajax中data字段的整理--包括json转换和spring注解

    1.前端$.ajax 的data为json提交的时候,后台方法中必须使用@RequestBody 注解    @RequestMapping(value = "getCpuData/{int ...

  7. NOLOCK、HOLDLOCK、UPDLOCK、TABLOCK、TABLOCKX

    NOLOCK(不加锁) 此选项被选中时,SQL Server 在读取或修改数据时不加任何锁. 在这种情况下,用户有可能读取到未完成事务(Uncommited Transaction)或回滚(Roll ...

  8. OpenJudge计算概论-配对碱基链

    /*===================================== 配对碱基链 总时间限制: 1000ms 内存限制: 65536kB 描述 脱氧核糖核酸(DNA)由两条互补的碱基链以双螺 ...

  9. python数据类型之 set

    set是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object set(iterabl ...

  10. java 获取实体类对象属性值的方法

    在java中我们要获得实体类对象的属性,一般情况是将实体类中的属性私有化,然后再对外提供get()与set()方法,然后再获取实体类对象的属性的时候先把对象new出来,再用变量名.get()的方法得到 ...