zoukankan      html  css  js  c++  java
  • 树链剖分(线段树区间更新求和(lazy操作)hdu3966)

    题意:给出一颗树形图,有三种操作,I:在u到v的路径上的每个点的权值+d,D:在u到v的路径上的每个点的权值都-d,Q询问u点的权值

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include"stdio.h"
    #include"string.h"
    #include"stdlib.h"
    #include"algorithm"
    #include"math.h"
    #include"vector"
    #include"queue"
    #include"map"
    #include"string"
    #define M 100009
    #define Maxm 10000
    #define inf 1000000000
    #define eps 1e-7
    #define pps 1e-18
    #define PI acos(-1.0)
    #define LL __int64
    using namespace std;
    struct node
    {
        int u,v,next;
    }edge[M*2];
    int t,head[M],son[M],num[M],p[M],fa[M],fp[M],deep[M],value[M],pos,top[M];
    void init()
    {
        t=pos=0;
        memset(head,-1,sizeof(head));
        memset(son,-1,sizeof(son));
    }
    void add(int u,int v)
    {
        edge[t].u=u;
        edge[t].v=v;
        edge[t].next=head[u];
        head[u]=t++;
    }
    void dfs(int u,int f,int d)
    {
        deep[u]=d;
        num[u]=1;
        fa[u]=f;
        for(int i=head[u];~i;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v!=f)
            {
                dfs(v,u,d+1);
                num[u]+=num[v];
                if(son[u]==-1||num[v]>num[son[u]])
                    son[u]=v;
            }
        }
    }
    void getpos(int u,int sp)
    {
        top[u]=sp;
        p[u]=++pos;
        fp[p[u]]=u;
        if(son[u]==-1)return;
        getpos(son[u],sp);
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v!=fa[u]&&v!=son[u])
                getpos(v,v);
        }
    }
    struct Tree
    {
        int l,r,add,flag;
    }tree[M*4];
    void push(int i)
    {
        if(tree[i].l==tree[i].r)return;
        if(tree[i].flag)
        {
            tree[i<<1].add+=tree[i].add;
            tree[i<<1].flag=1;
            tree[i<<1|1].add+=tree[i].add;
            tree[i<<1|1].flag=1;
            tree[i].flag=tree[i].add=0;
        }
    }
    void make(int l,int r,int i)
    {
        tree[i].l=l;
        tree[i].r=r;
        tree[i].flag=1;
        tree[i].add=0;
        if(l==r)
            return;
        int mid=(l+r)>>1;
        make(l,mid,i<<1);
        make(mid+1,r,i<<1|1);
    }
    void updata(int l,int r,int i,int k)
    {
        if(tree[i].l==l&&tree[i].r==r)
        {
            tree[i].add+=k;
            tree[i].flag=1;
            return;
        }
        push(i);
        int mid=(tree[i].l+tree[i].r)>>1;
        if(r<=mid)
            updata(l,r,i<<1,k);
        else if(l>mid)
            updata(l,r,i<<1|1,k);
        else
        {
            updata(l,mid,i<<1,k);
            updata(mid+1,r,i<<1|1,k);
        }
    }
    int query(int q,int i)
    {
        if(tree[i].l==q&&tree[i].r==q)
            return tree[i].add;
        push(i);
        int mid=(tree[i].l+tree[i].r)>>1;
        if(q<=mid)
            return query(q,i<<1);
        else
            return query(q,i<<1|1);
    }
    void lcp(int u,int v,int k)
    {
        int f1=top[u];
        int f2=top[v];
        while(f1!=f2)
        {
            if(deep[f1]<deep[f2])
            {
                swap(f1,f2);
                swap(u,v);
            }
            updata(p[f1],p[u],1,k);
            u=fa[f1];
            f1=top[u];
        }
        if(deep[u]>deep[v])
            swap(u,v);
        updata(p[u],p[v],1,k);
    }
    int main()
    {
        int n,m,Q,i,u,v,d;
        char str[5];
        while(scanf("%d%d%d",&n,&m,&Q)!=EOF)
        {
            for(i=1;i<=n;i++)
                scanf("%d",&value[i]);
            init();
            for(i=1;i<=m;i++)
            {
                scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
            }
            dfs(1,1,1);
            getpos(1,1);
            make(1,pos,1);
            while(Q--)
            {
                scanf("%s",str);
                if(str[0]=='I')
                {
                    scanf("%d%d%d",&u,&v,&d);
                    lcp(u,v,d);
                }
                else if(str[0]=='D')
                {
                    scanf("%d%d%d",&u,&v,&d);
                    lcp(u,v,-d);
                }
                else
                {
                    scanf("%d",&u);
                    printf("%d
    ",value[u]+query(p[u],1));
                }
            }
        }
        return 0;
    }
    


  • 相关阅读:
    取得窗口大小和窗口位置兼容所有浏览器的js代码
    一个简单易用的导出Excel类
    如何快速启动chrome插件
    网页表单设计案例
    Ubuntu下的打包解包
    The source file is different from when the module was built. Would you like the debugger to use it anyway?
    FFisher分布
    kalman filter
    Group delay Matlab simulate
    24位位图格式解析
  • 原文地址:https://www.cnblogs.com/mypsq/p/4348094.html
Copyright © 2011-2022 走看看