qtree(树链刨分)
来源:互联网 发布:上海地铁客流量数据 编辑:程序博客网 时间:2024/05/29 02:46
题意:给一棵树,两种操作:一条路径上所有数模一个值,求路径上的最大值。
一个数模一个比他小的数,再怎么都会至少减半,所以模可以暴力搞,总的暴力修改的次数在nlogn以内。其它的就好办了。
以前遇到过类似思路的题,有区间开根号,区间取对数的,这些都是下降得特别快的所以暴力来搞,这次在考场上由于一开始看错题了所以没想出来,以后要注意这类问题。
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int MAXN = 50010;inline void get(int&r) {char c; r = 0;do c=getchar(); while (c<'0'||c>'9');do r=r*10+c-'0', c=getchar(); while (c>='0'&&c<='9');}int N;struct Ed { int to; Ed*nxt;}Edges[MAXN*2], *ecnt=Edges, *adj[MAXN];inline void adde(int a, int b){(++ecnt)->to = b;ecnt->nxt = adj[a];adj[a] = ecnt;}int fa[MAXN], sz[MAXN], dep[MAXN];int htp[MAXN], hsn[MAXN], pp[MAXN];int a[MAXN], ref[MAXN];void DFS1(int u){sz[u] = 1;for (Ed*p = adj[u]; p; p=p->nxt)if (p->to != fa[u]) {fa[p->to] = u;dep[p->to] = dep[u] + 1;DFS1(p->to);sz[u] += sz[p->to];if (sz[p->to] > sz[hsn[u]]) hsn[u] = p->to;}}int tmr;int val[MAXN];void DFS2(int u, int tp){ htp[u] = tp;pp[u] = ++tmr;val[pp[u]] = a[u]; if (hsn[u]) DFS2(hsn[u], tp); for (Ed*p = adj[u]; p; p=p->nxt) if (p->to != hsn[u] && p->to != fa[u]) DFS2(p->to, p->to);}struct Node { int l, r, mx; };struct segtree {#define lch(x) ((x)<<1)#define rch(x) ((x)<<1|1)Node a[MAXN * 4];inline void pushup(int i){if (a[i].l != a[i].r)a[i].mx = max(a[lch(i)].mx, a[rch(i)].mx);}void build(int i, int l, int r){a[i].l = l, a[i].r = r;a[i].mx = val[l];if (l == r) return;build(lch(i), l, (l+r)>>1);build(rch(i), ((l+r)>>1)+1, r);pushup(i);}void modify(int i, int l, int r, int mo){if (a[i].mx < mo) return;if (a[i].l>r || a[i].r<l) return;if (a[i].l == a[i].r) { a[i].mx %= mo; return; }modify(lch(i), l, r, mo);modify(rch(i), l, r, mo);pushup(i);}int qmax(int i, int l, int r){if (a[i].l>r || a[i].r<l) return 0;if (a[i].l>=l && a[i].r<=r) return a[i].mx;return max(qmax(lch(i), l, r), qmax(rch(i), l, r));}} sg;void change(int u, int v, int x){ for (int f1=htp[u], f2=htp[v]; f1 != f2; ) {if (dep[f1] < dep[f2]) swap(f1,f2), swap(u, v);sg.modify(1, pp[f1], pp[u], x);u = fa[f1], f1 = htp[u]; } if (dep[u] > dep[v]) swap(u, v); sg.modify(1, pp[u], pp[v], x);}int ask(int u, int v){int ans = 0; for (int f1=htp[u], f2=htp[v]; f1 != f2; ) {if (dep[f1] < dep[f2]) swap(f1,f2), swap(u, v);ans = max(ans, sg.qmax(1, pp[f1], pp[u]));u = fa[f1], f1 = htp[u]; } if (dep[u] > dep[v]) swap(u, v);return max(ans, sg.qmax(1, pp[u], pp[v]));}int main(){get(N);int u, v, c;for (int i = 1; i<=N; ++i) get(a[i]);for (int i = 1; i<N; ++i)get(u), get(v), adde(u, v), adde(v, u);DFS1(1);DFS2(1, 1);sg.build(1, 1, N);int Q; get(Q);char op[10];while (Q --) {scanf("%s", op);get(u), get(v);if (op[0] == 'A') printf("%d\n", ask(u, v));else get(c), change(u, v, c);}return 0;}
0 0
- qtree(树链刨分)
- spoj QTREE - Query on a tree(树链刨分)
- SPOJ375.QTREE
- SPOJ QTREE
- [SPOJ375] QTREE
- SPOJ QTREE
- SPOJ375[QTREE
- Qtree树链剖分
- Spoj375 Qtree
- 【树链剖分】QtreeⅣ&QtreeⅤ题解
- 树链剖分(QTREE)
- SPOJ375 QTREE 树链剖分入门
- SPOJ QTREE LCT
- 【COGS1672】【SPOJ375】QTREE
- SPOJ - QTREE (树链剖分)
- SPOJ QTREE lct
- SPOJ QTREE 系列
- 【SPOJ QTREE】树链剖分模板
- 10G(82599EB) 网卡测试优化(总)
- 欧冠16强抽签概率计算器
- 获取焦点、监听软键盘、关闭软键盘、适应ListView控件
- Python 基础语法(一)
- PAT 1045 快速排序
- qtree(树链刨分)
- CSS的继承、层叠和特殊性
- Python 基础语法(二)
- HDU 2119 Matrix 二分图最小点覆盖
- c语言指针之void
- Python 基础语法(三)
- C++顺序性容器、关联性容器与容器适配器
- poj--1386
- HDOJ 1716 排列2 (next_permutation或dfs)