zoukankan      html  css  js  c++  java
  • [树链剖分]JZOJ 2677 树A

    Description


    已知无向连通图GN个点,N-1条边组成。每个点有给定权值。现有M个操作,操作分为2种:操作1,将某点权值更改;操作2,询问从点A至点B路径上所有点的权值和。

     

    Input


    每个输入文件中仅包含一个测试数据。


    第一行包含两个整数N,M


    第二行至第N行每行包含2个整数,AB,表示节点A与节点B有一条边相连。


    N+1行包含N个整数,表示第N个点的初始权值。


    N+2行至第N+M+1行每行包含三个整数,KAB(若K=1,表示将点A权值改为B;若K=2表示询问点A至点B路径上所有点的权值和)




    Output


    输出文件若干行,分别对应每次操作2的答案。

     

    Sample Input

    3 2
    1 2 
    1 3 
    1 2 3
    2 1 3
    2 2 3

    Sample Output

    4
    6
     

    Data Constraint

     
     

    Hint


    对于60%的数据,1<=N,M<=1000


    对于100%的数据,2<=N<=30000;0<=M<=200000

    分析

    树剖模板……

    #include <iostream>
    #include <cstdio>
    #define lson (x<<1)
    #define rson ((x<<1)+1)
    using namespace std;
    const int N=3e4+10;
    struct Graph {
        int v,nx;
    }g[2*N];
    int cnt,list[N];
    int top[N],sz[N],seg[N],f[N],dep[N],son[N],w[N];
    int t[4*N],scnt,rev[N],rt=1;
    int n,m;
    
    void Add(int u,int v) {
        g[++cnt]=(Graph){v,list[u]};list[u]=cnt;
        g[++cnt]=(Graph){u,list[v]};list[v]=cnt;
    }
    
    void DFS(int u,int fa) {
        dep[u]=dep[fa]+1;f[u]=fa;sz[u]=1;
        for (int i=list[u];i;i=g[i].nx)
            if (g[i].v!=fa) {
                DFS(g[i].v,u);
                sz[u]+=sz[g[i].v];
                if (sz[g[i].v]>sz[son[u]]) son[u]=g[i].v;
            }
    }
    
    void DFS(int u) {
        int s=son[u];
        if (s) {
            top[s]=top[u];
            rev[seg[s]=++scnt]=s;
            DFS(s);
        }
        for (int i=list[u];i;i=g[i].nx)
            if (!top[g[i].v]) top[g[i].v]=g[i].v,rev[seg[g[i].v]=++scnt]=g[i].v,DFS(g[i].v);
    }
    
    void Update(int x) {t[x]=t[lson]+t[rson];}
    
    void Build(int x,int l,int r) {
        if (l==r) {
            t[x]=w[rev[l]];
            return;
        }
        int mid=l+r>>1;
        Build(lson,l,mid);Build(rson,mid+1,r);
        Update(x);
    }
    
    void Change(int x,int l,int r,int k,int z) {
        if (k<l||r<k) return;
        if (l==r&&l==k) {
            t[x]=z;
            return;
        }
        int mid=l+r>>1;
        if (k<=mid) Change(lson,l,mid,k,z);
        else Change(rson,mid+1,r,k,z);
        Update(x);
    }
    
    int Query(int x,int l,int r,int ll,int rr) {
        if (r<l||rr<l||r<ll) return 0;
        if (ll<=l&&r<=rr) return t[x];
        int mid=l+r>>1,ans=0;
        if (ll<=mid) ans+=Query(lson,l,mid,ll,rr);
        if (mid<rr) ans+=Query(rson,mid+1,r,ll,rr);
        return ans;
    }
    
    int Query(int x,int y) {
        int fx=top[x],fy=top[y],ans=0;
        while (fx!=fy) {
            if (dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
            ans+=Query(rt,1,scnt,seg[fx],seg[x]);
            x=f[fx];fx=top[x];
        }
        if (dep[x]<dep[y]) swap(x,y),swap(fx,fy);
        return ans+Query(rt,1,scnt,seg[y],seg[x]);
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),Add(u,v);
        for (int i=1;i<=n;i++) scanf("%d",&w[i]);
        DFS(1,0);top[1]=1;rev[seg[1]=++scnt]=1;DFS(1);Build(rt,1,scnt);
        for (;m;m--) {
            int k,a,b;
            scanf("%d%d%d",&k,&a,&b);
            if (k==1) Change(rt,1,scnt,seg[a],b);
            else printf("%d
    ",Query(a,b));
        }
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    Modbus RTU与Modbus TCP的区别
    《对比Excel,轻松学习Python数据分析》笔记
    字符串 批量删除
    地图服务在线资源
    Java环境变量配置及maven配置
    Android学习路线
    MySQL备份脚本,应该这么写
    Windows中mysql5.6升级5.7
    SQL Server数据分析面试题(202008)
    PYTHON-未知错误
  • 原文地址:https://www.cnblogs.com/mastervan/p/11149089.html
Copyright © 2011-2022 走看看