zoukankan      html  css  js  c++  java
  • SP6779 GSS7

    纯数据结构题,没有思维难度。直接用线段树求最大子段和的方法完成树上路径的合并。注意链上合并顺序要符合序列的前后顺序。

    #include <cstdio>
    #include <cstring>
    #define cd w<<1
    const int S=200030;
    int n,Q,h[S],v[S],nx[S],d[S],e[S],s[S],eg=1,fa[S],t[S],f[S],_=0,rk[S],a[S],dep[S];
    inline int ma(int a,int b){return a>b?a:b;}
    inline int mi(int a,int b){return a>b?b:a;}
    inline void swap(int &a,int &b){a^=b^=a^=b;}
    inline void egadd(int uu,int vv)
    {
        nx[++eg]=h[uu];h[uu]=eg;
        v[eg]=vv;
    }
    struct node
    {
        int a,ls,rs,s,tag;
        
    };
    inline node merge(node b,node c)
    {
        node a;
        a.ls=ma(b.ls,b.s+c.ls);
        a.rs=ma(c.rs,c.s+b.rs);
        a.s=b.s+c.s;
        a.a=ma(b.a,c.a);
        a.a=ma(ma(a.ls,a.rs),ma(b.rs+c.ls,a.a));
        a.a=ma(a.a,0);
        a.ls=ma(a.ls,0);
        a.rs=ma(a.rs,0);
        return a;
    }	
    const int inf=(1<<30)-1;
    struct Sgtr
    {
        node sg[S<<2];
        inline int pos(int l,int r){return (l+r)|(l!=r);}
        void build(int l,int r)
        {
            int w=pos(l,r);
            // printf("Build (%d,%d)=%d
    ",l,r,w);
            if (l==r)
            {
                int x=a[rk[l]];
                // printf("--build (%d %d)
    ",rk[l],x);
                if (x>0)
                    sg[w]=(node){x,x,x,x,inf};
                else
                    sg[w]=(node){0,0,0,x,inf};
                return;
            }
            int mid=(l+r)>>1,lc=pos(l,mid),rc=pos(mid+1,r);
            build(l,mid);
            build(mid+1,r);
            sg[w]=merge(sg[lc],sg[rc]);
            sg[w].tag=inf;
        }
        void init()
        {
            memset(sg,0,sizeof(sg));
            build(1,n);
        }
        inline void pushdown(int w,int l,int mid,int r)
        {
            int lc=pos(l,mid),rc=pos(mid+1,r),x=sg[w].tag;
            if (x!=inf)
            {
                sg[lc].tag=sg[rc].tag=x;
                if (x>=0)
                {
                    sg[lc]=(node){(mid-l+1)*x,(mid-l+1)*x,(mid-l+1)*x,(mid-l+1)*x,x};
                    sg[rc]=(node){(r-mid)*x,(r-mid)*x,(r-mid)*x,(r-mid)*x,x};
                }
                else
                {
                    sg[lc]=(node){0,0,0,(mid-l+1)*x,x};
                    sg[rc]=(node){0,0,0,(r-mid)*x,x};
                }
            }
            sg[w].tag=inf;
        }
        void modify(int l,int r,int ll,int rr,int x)
        {
            int w=pos(l,r);
            // printf("MODIFY %d %d %d %d %d
    ",l,r,ll,rr,x);
            if (ll<=l && r<=rr)
            {
                if (x>=0)
                {
                    sg[w].a=sg[w].ls=sg[w].rs=sg[w].s=(r-l+1)*x;
                    sg[w].tag=x;
                }
                else
                {
                    sg[w].a=sg[w].ls=sg[w].rs=0;
                    sg[w].s=(r-l+1)*x;
                    sg[w].tag=x;
                }
                return;
            }
            int mid=(l+r)>>1,lc=pos(l,mid),rc=pos(mid+1,r);
            pushdown(w,l,mid,r);
            if (ll<=mid) modify(l,mid,ll,rr,x);
            if (rr>mid) modify(mid+1,r,ll,rr,x);
            sg[w]=merge(sg[lc],sg[rc]);
            sg[w].tag=inf;
        }
        node calcu(int l,int r,int ll,int rr)
        {
            int w=pos(l,r);
            // printf("(%d %d)=%d  %d %d
    ",l,r,w,ll,rr);
            if (ll<=l && r<=rr)
            {
                return sg[w];
            }
            int mid=(l+r)>>1;
            pushdown(w,l,mid,r);
            if (ll>mid) return calcu(mid+1,r,ll,rr);
            if (rr<=mid) return calcu(l,mid,ll,rr);
            node a,b,c;
            b=calcu(l,mid,ll,rr);
            c=calcu(mid+1,r,ll,rr);
            a=merge(b,c);
            return a;
        }
    }sg;
    void dfs_1(int x)
    {
        s[x]=1;
        for (int i=h[x];i;i=nx[i])
            if (v[i]!=fa[x])
            {
                fa[v[i]]=x;
                dep[v[i]]=dep[x]+1;
                dfs_1(v[i]);
                s[x]+=s[v[i]];
                if (s[v[i]]>s[e[x]])
                    e[x]=v[i];
            }
    }
    void dfs_2(int x,int top)
    {
        f[x]=++_;
        rk[_]=x;
        t[x]=top;
        if (!e[x]) return;
        dfs_2(e[x],top);
        for (int i=h[x];i;i=nx[i])
            if (v[i]!=fa[x] && v[i]!=e[x])
                dfs_2(v[i],v[i]);
    }
    void _modify(int x,int y,int o)
    {
        while (t[x]!=t[y])
        {
            if (dep[t[x]]<dep[t[y]])
                swap(x,y);
            sg.modify(1,n,f[t[x]],f[x],o);
            // printf("modify %d~%d
    ",t[x],x);
            x=fa[t[x]];
        }
        if (dep[x]>dep[y])
            swap(x,y);
        // printf("modify %d~%d
    ",x,y);
        sg.modify(1,n,f[x],f[y],o);
    }
    int _calcu(int x,int y)
    {
        node hida,migi,ans;
        hida=migi=(node){0,0,0,0,inf};
        while (t[x]!=t[y])
        {
            if (dep[t[x]]>dep[t[y]])
            {
                // printf("Calcu: x:%d~%d   value=%d 
    ",f[t[x]],f[x],hida.a);
                // printf("o=%d ",o.a);
                hida=merge(sg.calcu(1,n,f[t[x]],f[x]),hida);
                // printf(" v2=%d
    ",hida.a);
                x=fa[t[x]];
            }
            else
            {
                migi=merge(sg.calcu(1,n,f[t[y]],f[y]),migi);
                // printf("Calcu: y:%d~%d
    ",t[y],y);
                y=fa[t[y]];
            }
        }
        if (dep[x]<dep[y])
        {
            migi=merge(sg.calcu(1,n,f[x],f[y]),migi);
            y=x;
        }
        else
        {
            hida=merge(sg.calcu(1,n,f[y],f[x]),hida);
            x=y;
        }
        // printf("Lca=%d
    ",x);
        swap(hida.ls,hida.rs);
        ans=merge(hida,migi);
        return ans.a;
    }
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
            scanf("%d",a+i);
        for (int i=1,uu,vv;i<n;i++)
        {
            scanf("%d%d",&uu,&vv);
            egadd(uu,vv);
            egadd(vv,uu);
        }
        dfs_1(1);
        dfs_2(1,1);
        sg.init();
        // for (int i=1;i<=n;i++)
            // printf("(f=%d,%d,%d) ",f[i],a[i],sg.sg[sg.pos(f[i],f[i])].a);puts("");
        for (scanf("%d",&Q);Q--;)
        {
            int o,x,y,z;
            scanf("%d%d%d",&o,&x,&y);
            if (o==1)
                printf("%d
    ",_calcu(x,y));
            else
            {
                scanf("%d",&z);
                _modify(x,y,z);
            }
            // puts("---------------");sg.travel(1,n);
        }
    }
    
  • 相关阅读:
    Pizza Pie Charts – 基于 Snap SVG 框架的响应式饼图
    超好玩!10款神奇的字符图案 & 词汇云生成工具
    『摄影欣赏』15幅迷人的来自世界各地的婴儿照片【组图】
    CSS 魔法系列:纯 CSS 绘制图形(各种形状的钻石)
    【特别推荐】10款唯美浪漫的婚礼 & 结婚纪念网站模板
    25款创新的 PSD 格式搜索框设计素材【免费下载】
    时尚前沿:15个创意的 3D 字体设计艺术作品欣赏
    Resumable.js – 基于 HTML5 File API 的文件上传
    经典设计:17个最有效的学习着陆页设计的例子
    图标集锦:10套免费的社交媒体 & 社交网站图标
  • 原文地址:https://www.cnblogs.com/Algebra-hy/p/11145852.html
Copyright © 2011-2022 走看看