zoukankan      html  css  js  c++  java
  • hdu 3966 树链分割第一3遍

    真的不好意思说话。你写得越多,对风暴各种问题泄露,更离谱,有什么错有。。

    。但是,仍然有一个。同时经过规范的编写清晰的代码。不能认为是理所当然。。。

    树桩阵列版:

    #include<cstdio>
    #include<cstring>
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int M = 50100;
    int son[M],top[M],father[M],dep[M],ti[M],siz[M];
    int idx,tp,n;
    struct {
        int head;
    }H[M];
    struct {
        int v,next;
    }E[M];
    void dfs_1(int u,int fa){
        son[u] = 0;siz[u] = 1;father[u] = fa;dep[u] = dep[fa] + 1;
        for(int i=H[u].head;i!=-1;i=E[i].next){
            int v = E[i].v;
            if(v == fa)continue;
            dfs_1(v,u);
            siz[u] += siz[v];
            if(siz[son[u]] < siz[v])son[u] = v;
        }
    }
    void dfs_2(int u,int fa){
        top[u] = fa;
        ti[u] = idx++;
        if(son[u]) dfs_2(son[u],fa);
        for(int i=H[u].head;i!=-1;i=E[i].next){
            int v = E[i].v;
            if(v == father[u]|| v == son[u])continue;
            dfs_2(v,v);
        }
    }
    int lobit(int x){
        return x&(-x);
    }
    int num[M*2];
    void update(int x ,int d){
        while( x <= n){
            num[x] += d;
            x += lobit(x);
        }
    }
    void change(int u,int v,int w){
        int f1 = top[u];
        int f2 = top[v];
        while(f1 != f2){
            if(dep[f1] <dep[f2]){
                swap(f1,f2);
                swap(u,v);
            }
            update(ti[f1],w);
            update(ti[u]+1,-w);
            u = father[f1];f1 = top[u];
        }
        if(dep[u] > dep[v])swap(u,v);
        update(ti[u],w);
        update(ti[v]+1,-w);
    }
    int sum(int x){
        int ans = 0;
        while(x>0){
            ans += num[x];
            x -= lobit(x);
        }
        return ans;
    }
    
    void add(int u,int v){
        E[tp].v = v;
        E[tp].next = H[u].head;
        H[u].head = tp++;
    }
    void init(){
        memset(E,-1,sizeof(E));
        memset(H,-1,sizeof(H));
        memset(num,0,sizeof(num));
        tp = 0;
        idx = 1;
    }
    int findp(int x){
        return sum(ti[x]);
    }
    int a[M];
    int main(){
       // freopen("input.txt","r",stdin);
        int m,p,u,v,w;
        while(scanf("%d%d%d",&n,&m,&p)==3){
        init();
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            while(m -- ){
                scanf("%d%d",&u,&v);
                add(u,v);add(v,u);
            }
            dfs_1(1,1);
            dfs_2(1,1);
            for(int i=1;i<=n;i++){
               update(ti[i],a[i]);
               update(ti[i]+1,-a[i]);
            }
    
            char op[100];
            while (p--){
                scanf("%s%d",op,&u);
                if(op[0] == 'Q'){
                    printf("%d
    ",sum(ti[u]));
                }else {
                    scanf("%d%d",&v,&w);
                    if(op[0] == 'D')w = -w;
                    change(u,v,w);
                }
            }
    
        }
    }<span style="background-color: rgb(255, 0, 0);">
    </span>

    线段树版:

    #pragma comment(linker,"/STACK:100000000,100000000")
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    #define lson id << 1
    #define rson id << 1 | 1
    const int M = 50010;
    int a[M],top[M],ti[M],son[M],father[M],siz[M],dep[M];
    int tp,idx;
    struct {
        int head;
    }H[M*2];
    struct {
        int v,next;
    }E[M*4];
    void add(int u,int v){
        E[tp].v = v;
        E[tp].next = H[u].head;
        H[u].head = tp++;
    }
    void dfs_1(int u,int fa){
        son[u] = 0;siz[u] =1;dep[u] = dep[fa] + 1;father[u] = fa;
        for(int i=H[u].head;i!=-1;i=E[i].next){
            int v = E[i].v;
            if(v == fa)continue;
            dfs_1(v,u);
            siz[u] += siz[v];
            if(siz[v] > siz[son[u]])son[u] = v;
    
        }
    }
    void dfs_2(int u,int fa){
        ti[u] = ++idx;top[u] = fa;
        if(son[u])dfs_2(son[u],fa);
        for(int i=H[u].head;i!=-1;i=E[i].next){
            int v  =  E[i].v;
            if(v == father[u]||v == son[u])continue;
            dfs_2(v,v);
        }
    }
    /* 线段树*/
    
    struct Lintree{
        int l,r,w,mark;
        int mid(){
            return (l+r) / 2;
        }
    }node[M*4];
    void build_tree(int id,int l,int r){
        node[id].l = l;
        node[id].r = r;
        node[id].mark = 0;
        if(l == r)return;
    
        int mid = node[id].mid();
        build_tree(lson,l,mid);
        build_tree(rson,mid+1,r);
    }
    void push_down(int id){
        if(node[id].mark){
            node[lson].mark += node[id].mark;
            node[rson].mark += node[id].mark;
            node[id].mark = 0;
        }
    }
    void update(int id,int l,int r,int w){
        if(node[id].l == l && node[id].r == r){
               // cout <<"dfasf -->" <<l<<"dfsf" <<r<<endl;
            node[id].mark+=w;
            return;
        }
        push_down(id);
        int mid = node[id].mid();
        if(r <=mid)update(lson,l,r,w);
        else if(l > mid)update(rson,l,r,w);
        else {
            update(lson,l,mid,w);
            update(rson,mid+1,r,w);
        }
    }
    int query(int id,int x){
        if(node[id].l == x&&node[id].r == x ){
               // cout <<"<sdf>"<< node[id].w<<endl;
            return node[id].mark;
        }
        push_down(id);
        int mid = node[id].mid();
        if(x <=mid)return query(lson,x);
        else return  query(rson,x);
    }
    void change(int u,int v,int x){
       // cout <<u<<"**"<<v<<endl;
       int f1 = top[u],f2 = top[v];
       while(f1 != f2){
            if(dep[f1] < dep[f2]){
                swap(f1,f2);
                swap(u,v);
            }
            update(1,ti[f1],ti[u],x);
            u = father[f1];f1 = top[u];
       }
       //if(u == v)return
       if(dep[u] > dep[v])swap(u,v);
       update(1,ti[u],ti[v],x);
    }
    void init(){
        memset(E,-1,sizeof(E));
        memset(H,-1,sizeof(H));
        tp = idx = 0;
    }
    int main(){
        int n,m,p,u,v,w;
        //freopen("input.txt","r",stdin);
        while(~scanf("%d%d%d",&n,&m,&p)){
           init();
    
           for(int i=1;i<=n;i++)
              scanf("%d",&a[i]);
           while(m--) {
                scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
             }
            dfs_1(1,1);
            dfs_2(1,1);
            build_tree(1,1,n);
           char op[1000];
    
            while(p--){
                scanf("%s",op);
                if(op[0] == 'Q'){
                    scanf("%d",&u);
                printf("%d
    ",query(1,ti[u])+a[u]);
                }else {
                    scanf("%d%d%d",&u,&v,&w);
                    if(op[0] == 'D') w = -w;
                    change(u,v,w);
    
                }
            }
        }
    }
    



    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    vs2010 怎样设置文本编辑窗口和解决方案资源管理器同步?
    google浏览器如何导出书签
    C#面试题
    Inkscape tricks
    jupyter-notebook kernel died
    matplotlib 显示中文
    Ubuntu+apt-get update时的源
    vscode设置出错, 无法自动补全
    Ubuntu+vscode打不开
    Ubuntu+Firefox总是打不开网页
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4805140.html
Copyright © 2011-2022 走看看