zoukankan      html  css  js  c++  java
  • hdu3966_树链剖分

    近期在强化知识点深度。发现树链剖分不是非常会写了。

    回想一下改动操作:

    若两个点在同一条链上,则直接改动这段区间。

    若不在同一条链上,改动深度较大的点到其链顶端的区间,同一时候将这个点变为他所在链顶端的父亲,循环操作直到这两个点在同一条链上。就能够用上一种方法了。

    没实用LCA写是由于曾经被坑过,不但没有这样的方法好写。效率也不太让人惬意。

    主要是对另外一种情况怎样写有所遗忘。写道模版再给自己提个醒。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAXN 50005
    int n,m,q;
    vector<int> map[MAXN];
    int size[MAXN],fa[MAXN],son[MAXN],val[MAXN],tid[MAXN],_tid[MAXN],dep[MAXN],top[MAXN];
    int cnt;
    struct node
    {
        int l,r,val;
    }tree[MAXN<<2];
    void dfs1(int s,int f,int d)
    {
        size[s]=1;
        fa[s]=f;
        dep[s]=d;
        int len=map[s].size();
        for(int i=0;i<len;i++)
        {
            int e=map[s][i];
            if(e==f)continue;
            dfs1(e,s,d+1);
            size[s]+=size[e];
            if(son[s]==0)
            son[s]=e;
            else if(size[son[s]]<size[e])
            son[s]=e;
        }
    }
    void dfs2(int s,int t)
    {
        tid[s]=++cnt;
        _tid[cnt]=s;
        top[s]=t;
        if(son[s]!=0)
        dfs2(son[s],t);
        int len=map[s].size();
        for(int i=0;i<len;i++)
        {
            int e=map[s][i];
            if(e!=fa[s] && e!=son[s])
            dfs2(e,e);
        }
    }
    void build(int l,int r,int now)
    {
        tree[now].l=l;
        tree[now].r=r;
        tree[now].val=0;
        if(l==r)
        {
            tree[now].val=val[_tid[l]];
            return ;
        }
        int mid=(l+r)>>1;
        build(l,mid,now<<1);
        build(mid+1,r,now<<1|1);
    }
    void down(int now)
    {
        tree[now<<1].val+=tree[now].val;
        tree[now<<1|1].val+=tree[now].val;
        tree[now].val=0;
    }
    void update(int l,int r,int now,int num)
    {
        if(l==tree[now].l && r==tree[now].r)
        {
            tree[now].val+=num;
            return ;
        }
        if(tree[now].val)
        down(now);
        int mid=(tree[now].l+tree[now].r)>>1;
        if(r<=mid)
        update(l,r,now<<1,num);
        else if(l>mid)
        update(l,r,now<<1|1,num);
        else
        {
            update(l,mid,now<<1,num);
            update(mid+1,r,now<<1|1,num);
        }
    }
    void change(int s,int e,int num)
    {
        while(top[s]!=top[e])
        {
            if(dep[top[s]]<dep[top[e]])
            swap(s,e);
            update(tid[top[s]],tid[s],1,num);
            s=fa[top[s]];
        }
        if(dep[s]>dep[e])
        swap(s,e);
        update(tid[s],tid[e],1,num);
    }
    int query(int l,int now)
    {
        if(tree[now].l==l && tree[now].r==l)
        return tree[now].val;
        if(tree[now].val)
        down(now);
        int mid=(tree[now].l+tree[now].r)>>1;
        if(l<=mid)
        return query(l,now<<1);
        else
        return query(l,now<<1|1);
    }
    int main()
    {
        while(cin>>n>>m>>q)
        {
            memset(size,0,sizeof(size));
            memset(fa,0,sizeof(fa));
            memset(tid,0,sizeof(tid));
            memset(son,0,sizeof(son));
            cnt=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&val[i]);
                map[i].clear();
            }
            for(int i=1;i<n;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                map[a].push_back(b);
                map[b].push_back(a);
            }
            dfs1(1,-1,1);
            dfs2(1,1);
            build(1,n,1);
            while(q--)
            {
                char ch[5];
                int a,b,c;
                scanf("%s",ch);
                if(ch[0]=='Q')
                {
                    scanf("%d",&a);
                    printf("%d
    ",query(tid[a],1));
                }
                else
                {
                    scanf("%d%d%d",&a,&b,&c);
                    if(ch[0]=='I')
                    change(a,b,c);
                    else
                    change(a,b,-c);
                }
            }
        }
    }
    


  • 相关阅读:
    06-tree Shaking
    05-babel-解析高级js语法+polyfill按需注入
    Symbol.iterator
    回调
    finally
    then的参数
    通过简单例子看Promise(一)
    作为Promise构造函数参数的函数
    resolved和rejected
    resolve和reject
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6903356.html
Copyright © 2011-2022 走看看