CSU 1811 Tree Intersection 处理树问题的一个重要思路!!!
2016-09-06 18:12
447 查看
http://acm.hust.edu.cn/vjudge/contest/131505#problem/I
给下链接 题意自取
错误思路不谈,避免强化
对题意简单理解后转化为
①求出每棵子树中独有的颜色 和 没出现过的颜色的数量
1. 比赛一打玩问 lcy 韬神 他们怎么做的,n个map 存该点下子树中需要存的颜色
据说复杂度可以证明为nlogn,不太懂 暂且不管
update: 证明就是启发式合并的证明//还没弄懂
map::swap的复杂度是常数的
2. 百度了一个做法超级神奇
先用dfs序将树转化为线段,然后莫队算法求
关键点一:将树转化为线段是想过,但懵逼选手只想到了树剖和LCA那个转化方式,显然两个都不适用就放弃了
然而dfs序转化树的题目做过两道了啊,居然没有想起来,给自己跪了
关键点二:将①转化为求
②每棵字数中独有的颜色 和 出现过的颜色的数量
关键点三:在区间上这个问题又如何做呢,因为拆成区间了,第一反应是线段树搞一下,然后就不知道如何合并了又GG
然后莫队出现了!
总结一些思路
将树拆为区间->三种,分别树剖,LCA, dfs序, 分别解决三种问题
区间查询问题->线段树/st/BIT 以及 莫队
给下链接 题意自取
错误思路不谈,避免强化
对题意简单理解后转化为
①求出每棵子树中独有的颜色 和 没出现过的颜色的数量
1. 比赛一打玩问 lcy 韬神 他们怎么做的,n个map 存该点下子树中需要存的颜色
据说复杂度可以证明为nlogn,不太懂 暂且不管
update: 证明就是启发式合并的证明//还没弄懂
map::swap的复杂度是常数的
2. 百度了一个做法超级神奇
先用dfs序将树转化为线段,然后莫队算法求
关键点一:将树转化为线段是想过,但懵逼选手只想到了树剖和LCA那个转化方式,显然两个都不适用就放弃了
然而dfs序转化树的题目做过两道了啊,居然没有想起来,给自己跪了
关键点二:将①转化为求
②每棵字数中独有的颜色 和 出现过的颜色的数量
关键点三:在区间上这个问题又如何做呢,因为拆成区间了,第一反应是线段树搞一下,然后就不知道如何合并了又GG
然后莫队出现了!
总结一些思路
将树拆为区间->三种,分别树剖,LCA, dfs序, 分别解决三种问题
区间查询问题->线段树/st/BIT 以及 莫队
#include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <set> #include <map> #include <queue> #include <algorithm> #include <stack> #include <cctype> #include <cmath> #include <vector> #include <sstream> #include <bitset> #include <deque> #include <iomanip> using namespace std; #define pr(x) cout << "x = " << x << endl; #define bug cout << "bugbug" << endl; #define ppr(x, y) printf("(%d, %d)\n", x, y); #define pfun(a, b) printf("x = %d f(x) = %d\n", a, b); typedef long long ll; typedef pair<int, int> P; typedef unsigned int uint; const int MOD = 1e9 + 7; const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3f; const int maxn = 1e5 + 4; const int maxm = 1e3 + 4; int n, col[maxn], c[maxn], u, v, S[maxn], T[maxn], Index, belong[maxn], cnt[maxn], in[maxn]; bool vis[maxn]; int a[maxn], b[maxn], fa[maxn]; vector<int> G[maxn]; void dfs(int u){ c[Index] = col[u]; S[u] = Index++; vis[u] = true; for (int i = 0; i < G[u].size(); ++i){ int v = G[u][i]; if (vis[v]) continue; fa[v] = u; dfs(v); } T[u] = Index - 1; } struct Query{ int l, r, id; bool operator < (const Query a390 &rhs) const{ if (belong[l] == belong[rhs.l]) return r < rhs.r; return belong[l] < belong[rhs.l]; } }q[maxn]; int ans[maxn], tot, full; inline void add(int pos){ if (in[c[pos]] == 0) tot++; if (++in[c[pos]] == cnt[c[pos]]) full++; return; } inline void sub(int pos){ if (in[c[pos]] == cnt[c[pos]]) full--; if (--in[c[pos]] == 0) tot--; return; } int main(){ //必须编译过才能交 // ios::sync_with_stdio(false); int ik, i, j, k, kase; while(~scanf("%d", &n)){ memset(in, 0, sizeof in); memset(cnt, 0, sizeof cnt); for (i = 1; i <= n; ++i){ scanf("%d", col + i); cnt[col[i]]++; } for (i = 1; i <= n; ++i) G[i].clear(); for (i = 1; i < n; ++i){ scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); a[i] = u; b[i] = v; } fa[1] = -1; memset(vis, false, sizeof vis); Index = 1; dfs(1); int bk = sqrt(n + 1); for (i = 1; i <= n; ++i){ belong[i] = i / bk; q[i].l = S[i]; q[i].r = T[i]; q[i].id = i; } sort(q+1, q+1+n); int lft = 1, rght = 0; tot = 0, full = 0; for (i = 1; i <= n; ++i){ Query& qu = q[i]; while(rght < qu.r) add(++rght); while(lft > qu.l) add(--lft); while(rght > qu.r) sub(rght--); while(lft < qu.l) sub(lft++); ans[qu.id] = tot - full; // cout << qu.id << ' ' << tot << ' ' << full << endl; } for (i = 1; i <= n - 1; ++i){ // printf("%d: ", fa[a[i]] == b[i] ? a[i] : b[i]); printf("%d\n", fa[a[i]] == b[i] ? ans[a[i]] : ans[b[i]]); } } return 0; }
相关文章推荐
- 当一个有性能问题的数据库摆在你的面前,作为责任人,你的处理思路是什么?
- 当一个有性能问题的数据库摆在你的面前,作为责任人,你的处理思路
- 触发器(当2个表中的相应值改变时同时改变一个表中的一个字段)(同时有处理“无法解决 equal to 操作的排序规则冲突”问题)
- csdn一个有关影像处理问题帖子的解答
- 一个发票处理的问题 Second time in above shift
- (求助)一个关于ACCESS数据库转化到MYSQL后的处理问题
- 一个iBatis框架进行batch处理的问题
- Asp.net中如何处理一个站点不同Web应用通用Session的问题
- 今天在处理GridView分页问题时遇到了一个比较常见的分页出错问题。
- 前台一个日期处理问题
- VC调用Delphi写的dll的一个问题的处理
- Hi!现在处理spring的一个问题java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
- 处理一个电脑启动问题
- Asp.net中处理一个站点不同Web应用共享Session的问题
- 水晶报表的一个重要问题,谁能帮我解决?
- 处理一个傻子引发得问题
- 一个重要问题
- 从一个网页传送表单到别一个网页时的中文处理问题
- "Visual studio .net 无法创建或打开应用程序" 问题的一个解决思路
- 用js写的一个形式为##.dd的动态小数掩码问题,可以处理负值 NumberMask