• SPOJ375 Query on a tree(树链剖分)


    传送门

    题意

    给出一棵树,每条边都有权值,有两种操作:

    • 把第p条边的权值改为x
    • 询问x,y路径上的权值最大的边

    code

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #define lson l,m,rt<<1
      5 #define rson m+1,r,rt<<1|1
      6 
      7 using namespace std;
      8 
      9 const int N = 100010;
     10 struct Edge {
     11     int to,nxt,w;
     12 }e[200100];
     13 int head[N],tot,tn,n;
     14 int deth[N],son[N],fa[N],siz[N],bel[N],pos[N];
     15 int mx[N<<2],a[N],b[N],c[N],data[N];
     16 
     17 void init() {
     18     tot = tn = 0;
     19     memset(head,0,sizeof(head));
     20     memset(son,0,sizeof(son));
     21 }
     22 inline void add_edge(int u,int v,int w) {
     23     e[++tot].to = v,e[tot].w = w,e[tot].nxt = head[u],head[u] = tot;
     24 }
     25 void dfs1(int u,int pa) {
     26     siz[u] = 1;
     27     for (int i=head[u]; i; i=e[i].nxt) {
     28         int v = e[i].to;
     29         if (v==pa) continue;
     30         fa[v] = u;
     31         deth[v] = deth[u] + 1;
     32         dfs1(v,u);
     33         siz[u] += siz[v];
     34         if (son[u]==0 || siz[v] > siz[son[u]]) son[u] = v;
     35     }
     36 }
     37 void dfs2(int u,int top) {
     38     pos[u] = ++tn;
     39     bel[u] = top;
     40     if (!son[u]) return ;
     41     dfs2(son[u],top);
     42     for (int i=head[u]; i; i=e[i].nxt) {
     43         int v = e[i].to;
     44         if (v != fa[u] && v != son[u]) dfs2(v,v);
     45     }
     46 }
     47 void pushup(int rt) {
     48     mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
     49 }
     50 void build(int l,int r,int rt) {
     51     if (l==r) {
     52         mx[rt] = data[l];return ;
     53     }
     54     int m = (l + r) >> 1;
     55     build(lson);
     56     build(rson);
     57     pushup(rt);
     58 }
     59 void update(int l,int r,int rt,int p,int x) {
     60     if (l==r) {
     61         mx[rt] = x;return ;
     62     }
     63     int m = (l + r) >> 1;
     64     if (p <= m) update(lson,p,x);
     65     else update(rson,p,x);
     66     pushup(rt);
     67 }
     68 int query(int l,int r,int rt,int L,int R) {
     69     if (L <= l && r <= R) {
     70         return mx[rt]; 
     71     }
     72     int m = (l + r) >> 1;
     73     int ret = -1e9;
     74     if (L <= m) ret = max(ret,query(lson,L,R));
     75     if (R > m)  ret = max(ret,query(rson,L,R));
     76     return ret;
     77 }
     78 void Change(int p,int x) {
     79     if (deth[a[p]] > deth[b[p]]) update(2,n,1,pos[a[p]],x);
     80     else update(2,n,1,pos[b[p]],x);
     81 }
     82 int Ask(int x,int y) {
     83     int ans = -1e9;
     84     while (bel[x] != bel[y]) {
     85         if (deth[bel[x]] < deth[bel[y]]) swap(x,y);
     86         ans = max(ans,query(2,n,1,pos[bel[x]],pos[x]));
     87         x = fa[bel[x]];
     88     }
     89     if (deth[x] > deth[y]) swap(x,y);
     90     if (x != y) ans = max(ans,query(2,n,1,pos[x]+1,pos[y]));
     91     return ans;
     92 }
     93 int main() {
     94     char opt[15];
     95     int T;scanf("%d",&T);
     96     while (T--) {
     97         init();
     98         scanf("%d",&n);
     99         for (int i=1; i<n; ++i) {
    100             scanf("%d%d%d",&a[i],&b[i],&c[i]);
    101             add_edge(a[i],b[i],c[i]);
    102             add_edge(b[i],a[i],c[i]);
    103         }
    104         deth[1] = 1;
    105         dfs1(1,0);
    106         dfs2(1,1);
    107         for (int i=1; i<n; ++i) {
    108             if (deth[a[i]] > deth[b[i]]) data[pos[a[i]]] = c[i]; // 一定是pos 
    109             else data[pos[b[i]]] = c[i];
    110         }
    111         build(2,n,1);
    112         scanf("%s",opt);
    113         while (opt[0]!='D') {
    114             int x,y;
    115             scanf("%d%d",&x,&y);
    116             if (opt[0]=='Q') printf("%d
    ",Ask(x,y));
    117             else Change(x,y);
    118             scanf("%s",opt);
    119         }
    120     }
    121     return 0;
    122 } 
  • 相关阅读:
    python数据分析之csv/txt数据的导入和保存
    SQL Server日志文件过大 大日志文件清理方法 不分离数据库
    socket--多进程,多线程服务器
    MYSQL千万级数据表,创建表及字段扩展的几条建议
    常见WEB攻击
    jQuery学习笔记之Ajax用法详解
    redis范围查询应用 数据库 数据库学习 Redis redis范围查询的方法
    CentOS 7下使用RPM安装mysql的方法。
    MySQL Daemon failed to start错误解决办法是什么呢?
    windows无法启动MySQL服务报错1067的解决方法是怎样?
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8120135.html
Copyright © 2020-2023  润新知