zoukankan      html  css  js  c++  java
  • HDU

    题目链接:传送门

    题目大意:给你一棵无根树,每个树节点上有权值,有三种操作,I x y v(从x到y的路径上每个点权值+v)

         D x y v(从x到y的路径上每个点权值-v)Q x(树节点为x 的权值是多少,权值可以为负)

    题目思路:树链剖分

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <stack>
    #include <cctype>
    #include <queue>
    #include <string>
    #include <vector>
    #include <set>
    #include <map>
    #include <climits>
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define fi first
    #define se second
    #define ping(x,y) ((x-y)*(x-y))
    #define mst(x,y) memset(x,y,sizeof(x))
    #define mcp(x,y) memcpy(x,y,sizeof(y))
    using namespace std;
    #define gamma 0.5772156649015328606065120
    #define MOD 1000000007
    #define inf 0x3f3f3f3f
    #define N 50005
    #define maxn 30010
    typedef pair<int,int> PII;
    typedef long long LL;
    LL read(){
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int n,m,k,L,R;
    struct Node{int to,nxt,v;}node[N<<1];
    int head[N],hcnt;
    int a[N],seg[N<<2],mrk[N<<2];
    int siz[N];     ///当前节点所含儿子的数量
    int top[N];     ///当前节点所在链的顶端
    int son[N];     ///当前节点的重儿子
    int fa[N];      ///当前节点的父节点
    int dep[N];     ///当前节点的深度
    int id[N],tid;  ///当前节点的新编号
    int posi[N];    ///当前节点在线段树中位置
    
    void init(){
        mst(head,-1);mst(mrk,0);hcnt=tid=0;
        mst(son,0);mst(siz,0);mst(id,0);mst(seg,0);
    }
    inline void addedge(int x,int y){
        node[hcnt].to=y,node[hcnt].nxt=head[x],head[x]=hcnt++;
        node[hcnt].to=x,node[hcnt].nxt=head[y],head[y]=hcnt++;
    }
    void dfs1(int u,int f,int deep){    ///确定重边和节点深度
        fa[u]=f;
        siz[u]=1;
        dep[u]=deep;
        for(int i=head[u];~i;i=node[i].nxt){
            int e=node[i].to;
            if(e==f)continue;
            dfs1(e,u,deep+1);
            siz[u]+=siz[e];
            if(!son[u]||siz[son[u]]<siz[e])
                son[u]=e;
        }
    }
    void dfs2(int u,int tp){    ///连边成链
        top[u]=tp;
        id[u]=++tid;
        posi[id[u]]=u;
        if(!son[u])return;
        dfs2(son[u],tp);
        for(int i=head[u];~i;i=node[i].nxt){
            int e=node[i].to;
            if(!id[e]) dfs2(e,e);///***和 e!=son[u]&&e!=fa[u] 无区别?
        }
    }
    void build(int rt,int l,int r){
        if(l==r){
            seg[rt]=a[posi[l]];
            return;
        }
        int mid=l+r>>1;
        build(lson);build(rson);
    }
    void pushdown(int rt){
        mrk[rt<<1]+=mrk[rt];
        mrk[rt<<1|1]+=mrk[rt];
        seg[rt<<1]+=mrk[rt];
        seg[rt<<1|1]+=mrk[rt];
        mrk[rt]=0;
    }
    void add(int rt,int l,int r,int v){
        if(L<=l&&r<=R){
            seg[rt]+=v;
            mrk[rt]+=v;
            return;
        }
        if(mrk[rt])pushdown(rt);
        int mid=l+r>>1;
        if(L<=mid)add(lson,v);
        if(R>mid)add(rson,v);
    }
    int query(int rt,int l,int r,int pos){
        if(l==r){return seg[rt];}
        int mid=l+r>>1;
        if(mrk[rt])pushdown(rt);
        if(pos<=mid)return query(lson,pos);
        else return query(rson,pos);
    }
    int main(){
        //freopen("in.txt","r",stdin);
        int i,j,group,x,y,v,Case=0;
        while(scanf("%d",&n)!=EOF){
            init();
            m=read();k=read();
            for(i=1;i<=n;++i) a[i]=read();
            while(m--){
                x=read();y=read();
                addedge(x,y);
            }
            dfs1(1,1,1);
            dfs2(1,1);
            build(1,1,n);
            char ch;
            while(k--){
                scanf(" %c",&ch);
                if(ch=='Q'){
                    x=read();
                    printf("%d
    ",query(1,1,n,id[x]));
                    continue;
                }
                x=read();y=read();v=read();if(ch=='D')v=-v;
                while(top[x]!=top[y]){
                    if(dep[top[x]]<dep[top[y]])swap(x,y);
                    L=id[top[x]];R=id[x];
                    add(1,1,n,v);
                    x=fa[top[x]];
                }
                if(dep[x]>dep[y])swap(x,y);
                L=id[x],R=id[y];
                add(1,1,n,v);
            }
        }
        return 0;
    }
  • 相关阅读:
    模拟光照中的凹凸纹理原理和应用
    Visual Studio 2010 SP1正式开放下载
    同桌的你网工版
    [转载]同桌的你程序员版
    学习计划:SSIS
    基于Java的HTML解析器
    初次使用NHibernate遇到的问题
    .NET下开源CMS系统汇总
    MyEclipse、Tomcat启动项目报错
    VBA 分文件夹 分excel
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5898136.html
Copyright © 2011-2022 走看看