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