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
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    Oracle 推出 ODAC for Entity Framework 和 LINQ to Entities Beta版
    Entity Framework Feature CTP 5系列文章
    MonoDroid相关资源
    MSDN杂志上的Windows Phone相关文章
    微软学Android Market推出 Web Windows Phone Marketplace
    使用 Visual Studio Agent 2010 进行负载压力测试的安装指南
    MonoMac 1.0正式发布
    Shawn Wildermuth的《Architecting WP7 》系列文章
    使用.NET Mobile API即51Degrees.mobi检测UserAgent
    MongoDB 客户端 MongoVue
  • 原文地址:https://www.cnblogs.com/mastervan/p/11149089.html
Copyright © 2011-2022 走看看