题意是给定一棵树。同时,给定如下k个查询:

给出任意两点u,v,对u到v的路径所经过的边进行加计数。

k个查询后,分别输出各边的计数之和。

思路利用LCA,对cnt[u]++, cnt[v]++,并对cnt[LCA(u, v)] -= 2.
然后dfs求解各边的计数。

 /* 191C */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int maxn = 1e5+;
const int maxd = ;
vpii E[maxn];
bool visit[maxn];
int ans[maxn];
int cnt[maxn];
int deep[maxn];
int pre[maxn][maxd]; void dfs(int u, int fa) {
int sz = SZ(E[u]), v; deep[u] = deep[fa] + ;
rep(i, , sz) {
v = E[u][i].fir;
if (v == fa)
continue;
pre[v][] = u;
rep(j, , maxd)
pre[v][j] = pre[pre[v][j-]][j-];
dfs(v, u);
}
} int LCA(int u, int v) {
if (deep[u] > deep[v])
swap(u, v);
if (deep[u] < deep[v]) {
int tmp = deep[v] - deep[u];
rep(i, , maxd) {
if (tmp & (<<i))
v = pre[v][i];
}
} if (u != v) {
per(i, , maxd) {
if (pre[u][i] != pre[v][i]) {
u = pre[u][i];
v = pre[v][i];
}
}
return pre[u][];
} else {
return u;
}
} int dfs2(int u, int eid) {
int ret = , sz = SZ(E[u]);
int e, v; visit[u] = true;
rep(i, , sz) {
v = E[u][i].fir;
e = E[u][i].sec;
if (!visit[v]) {
ret += dfs2(v, e);
}
}
ret += cnt[u];
ans[eid] = ret; return ret;
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int n;
int u, v, fa; scanf("%d", &n);
rep(i, , n) {
scanf("%d %d", &u, &v);
E[u].pb(mp(v, i));
E[v].pb(mp(u, i));
} dfs(, ); int k; scanf("%d", &k);
while (k--) {
scanf("%d %d", &u, &v);
fa = LCA(u, v);
++cnt[u];
++cnt[v];
cnt[fa] -= ;
} dfs2(, );
rep(i, , n)
printf("%d ", ans[i]);
putchar('\n'); #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

【CF】121 Div.1 C. Fools and Roads的更多相关文章

  1. 【CF】310 Div.1 C. Case of Chocolate

    线段树的简单题目,做一个离散化,O(lgn)可以找到id.RE了一晚上,额,后来找到了原因. /* 555C */ #include <iostream> #include <str ...

  2. 【CF】110 Div.1 B. Suspects

    这题目乍眼一看还以为是2-sat.其实很水的,O(n)就解了.枚举每个人,假设其作为凶手.观察是否满足条件.然后再对满足的数目分类讨论,进行求解. /* 156B */ #include <io ...

  3. 【CF】222 Div.1 B Preparing for the Contest

    这样类似的题目不少,很多都是一堆优化条件求最优解,这个题的策略就是二分+贪心.对时间二分, 对费用采用贪心. /* 377B */ #include <iostream> #include ...

  4. 【CF】207 Div.1 B.Xenia and Hamming

    这题目一看很牛逼,其实非常easy.求求最小公倍数,最大公约数,均摊复杂度其实就是O(n). /* 356B */ #include <iostream> #include <str ...

  5. 【CF】142 Div.1 B. Planes

    SPFA.注意状态转移条件,ans的求解需要在bfs中间求解.因为只要到了地点n,则无需等待其他tourist.还是蛮简单的,注意细节. /* 229B */ #include <iostrea ...

  6. 【CF】196 Div.2 D. Book of Evil

    显然这个图是一课树,看着题目首先联想到LCA(肯定是可以解的).但是看了一下数据大小,应该会TLE.然后,忽然想到一个前面做过的题目,大概是在一定条件下树中某结点旋转成为根后查询最长路径.结果灵感就来 ...

  7. 【CF】223 Div.1 C Sereja and Brackets

    水线段树. /* 380C */ #include <iostream> #include <string> #include <map> #include < ...

  8. 【CF】259 Div.1 B Little Pony and Harmony Chest

    还蛮有趣的一道状态DP的题目. /* 435B */ #include <iostream> #include <string> #include <map> #i ...

  9. 【CF】174 Div.1 B Cow Program

    思路是树形DP+状态压缩.其实仅有2个状态,奇数次来到x或者偶数次来到x.(因为对x的更新不同).同时开辟visit数组,解决环.注意,一旦遇到环结果就是-1.DP数组存放第奇数/偶数次来到x时,对y ...

随机推荐

  1. Javaweb入门20160301 ---xml入门

    一.xml语法 1.文档声明 用来声明xml的基本属性,用来指挥解析引擎如何去解析当前xml 通常一个xml都要包含并且只能包含一个文档声明 xml的文档必须在整个xml的最前面,在文档声明之前不能有 ...

  2. 使用sqlldr命令导入资料到Oracle数据库表中的示例说明

    CSV: Comma-Separated Values(逗号分隔值)的缩写,是以逗号分隔字段的多行文本文件   sqlldr 是sql*loader的缩写,此工具在安装完整版的Oracle客户端后就有 ...

  3. swift入门-day02

    1.函数 2.闭包 3.构造函数基础 4.重载构造函数 5.KVC构造函数 6.遍历构造函数 7.懒加载 8.只读属性 1.函数 掌握函数的定义 掌握外部参数的用处 掌握无返回类型的三种函数定义方式 ...

  4. OC与Swift的区别三(条件语句)

    11.swift中的switch结构 区别一: oc中switch条件只可以放整数 swift中switch条件可以放几乎任何数据类型 区别二: oc中每一个case中应有break,如果没有brea ...

  5. 常用数据结构[OpenCV 笔记12]

    Point 二维坐标系下的整数点, 定义如下 typedef Point_<int> Point2i; typedef Point2i Point; typedef Point_<f ...

  6. IOS 学习日志 2015-3-16

    Objective--C 一 关键字 self 相当于java中的this,但是又有不同 它即可一代替对象,也可以代替类, 也就是说它既可以用在静态方法中又可以用在动态方法中. super 相当于父类 ...

  7. hibernate细节一

    public void saveUser(){        Session session=JdbcUtil.getSession();        User user=new User();   ...

  8. linux shell 逻辑运算符

    一.逻辑卷标 逻辑卷标 表示意思 1. 关于档案与目录的侦测逻辑卷标! -f 常用!侦测『档案』是否存在 eg: if [ -f filename ] -d 常用!侦测『目录』是否存在 -b 侦测是否 ...

  9. js 中如何通过提示框跳转页面

    通过提示框跳转页面 <!doctype html> <html lang="en"> <head> <meta charset=" ...

  10. Git中的fetch和pull

    http://blog.haohtml.com/archives/12674 Git中从远程的分支获取最新的版本到本地有这样2个命令: 1. git fetch:相当于是从远程获取最新版本到本地,不会 ...