SPOJ 10707 Count on a Tree II 树上莫队
来源:互联网 发布:涂鸦移动 知乎 编辑:程序博客网 时间:2024/05/21 22:37
查询树点对间不同数字的个数。
为什么我的程序越改越慢。。。
#include <cstdio>#include <cmath>#include <algorithm>using namespace std;#define FOR(i,j,k) for(i=j;i<=k;++i)const int N = 40005, M = 100005, K = 16;int block[M];struct Query { int l, r, i; } q[M];bool operator <(const Query &a, const Query &b) { return block[a.l] == block[b.l] ? a.r < b.r : a.l < b.l;}int v[M], p[M], h[N], cnt;void add(int x, int y) { v[++cnt] = y, p[cnt] = h[x], h[x] = cnt; }int beg[N], end[N], dfn[M], dep[N], fa[N][20], id[N], ID, ts;void dfs(int x, int f) { int i; id[x] = ++ID; dfn[beg[x] = ++ts] = x; dep[x] = dep[f] + 1; fa[x][0] = f; FOR(i,1,K) fa[x][i] = fa[fa[x][i - 1]][i - 1]; for (i = h[x]; i; i = p[i]) if (v[i] != f) dfs(v[i], x); dfn[end[x] = ++ts] = x;}int lca(int x, int y) { if (dep[x] < dep[y]) swap(x, y); int t = dep[x] - dep[y], i; for (i = 0; i <= K; ++i) if ((1 << i) & t) x = fa[x][i]; for (i = K; i >= 0; --i) if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i]; return x == y ? x : fa[x][0];}int now, vis[N], sum[N], a[N], b[N], ans[M];void modify(int x) { if (vis[x]) { if (!--sum[a[x]]) --now; } else { if (!sum[a[x]]++) ++now; } vis[x] = !vis[x]; }void transform(int &l, int &r, int &ans, int ql, int qr) { while (r < qr) modify(dfn[++r]); while (r > qr) modify(dfn[r--]); while (l < ql) modify(dfn[l++]); while (l > ql) modify(dfn[--l]); int x = dfn[l], y = dfn[r]; int t = lca(x, y); if (t != x && t != y) modify(t); ans = now; if (t != x && t != y) modify(t);}int main() { int n, m, x, y, i, sz, t, l = 1, r = 0; scanf("%d%d", &n, &m); FOR(i,1,n) scanf("%d", &a[i]), b[i] = a[i]; sort(b + 1, b + n + 1); FOR(i,1,n) a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b; FOR(i,2,n) scanf("%d%d", &x, &y), add(x, y), add(y, x); dfs(1, 1); sz = sqrt(ts); FOR(i,1,ts) block[i] = (i - 1) / sz + 1; FOR(i,1,m) { scanf("%d%d", &x, &y); if (id[x] > id[y]) swap(x, y); q[i] = (Query) { lca(x, y) == x ? beg[x] : end[x], beg[y], i }; } sort(q + 1, q + m + 1); FOR(i,1,m) transform(l, r, ans[q[i].i], q[i].l, q[i].r); FOR(i,1,m) printf("%d\n", ans[i]); return 0;}
COT2 - Count on a tree II
no tags
You are given a tree with N nodes.The tree nodes are numbered from 1 to N.Each node has an integer weight.
We will ask you to perfrom the following operation:
u v : ask for how many different integers that represent the weight of nodes there are on the path from u to v.
Input
In the first line there are two integers N and M.(N<=40000,M<=100000)
In the second line there are N integers.The ith integer denotes the weight of the ith node.
In the next N-1 lines,each line contains two integers u v,which describes an edge (u,v).
In the next M lines,each line contains two integers u v,which means an operation asking for how many different integers that represent the weight of nodes there are on the path from u to v.
Output
For each operation,print its result.
Example
Input:
8 58 2
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5
7 8
Output:
4
4
- SPOJ 10707 Count on a Tree II 树上莫队
- SPOJ--Count on a tree II(树上莫队)
- SPOJ COT2 Count on a tree II [树上莫队]
- SPOJ COT2 Count on a tree II 树上莫队
- 【SPOJ COT2】Count on a tree II,树上莫队
- SPOJ-COT2 Count on a tree II(树上莫队)
- [树上莫队] SPOJ COT2 Count on a tree II
- [spoj COT2- Count on a tree II] 树上莫队
- SPOJ Count on a tree II(树上莫队)
- 【spoj】【COT2 - Count on a tree II】【莫队算法】
- BZOJ 2589 Spoj 10707 Count on a tree II 强制在线莫队算法(TLE)
- SPOJ COT2 Count on a tree II
- SPOJ Count on a tree 树上第k大。
- Spoj 10628. Count on a tree 树上主席树
- SPOJ COT Count on a tree 树上第k小
- SPOJ Count on a tree(树上第K大)
- spoj_cot2 Count on a tree II(树上莫队+离散化)
- SPOJ Count on a tree
- 第一个JavaScript
- 设计模式-原型模式
- 一文读懂机器学习,大数据/自然语言处理/算法全有了……
- 生产者/消费者模式(阻塞队列)
- 迟到的总结(三)--springmvc的系统学习之数据的处理,乱码及restful
- SPOJ 10707 Count on a Tree II 树上莫队
- Java集合类
- java内置对象三
- spring-hibernate修改数据报错
- mysql主从配置完整版(二进制安装)
- Scala 匿名函数
- ndnSIM模块——helpers
- 把一元硬币换成1分,2分5分的硬币有几种不同的方法
- [BZOJ 1042][HAOI2008]硬币购物