zoukankan      html  css  js  c++  java
  • XCOJ 1103 (LCA+树链最大子段和)

    题目链接http://xcacm.hfut.edu.cn/problem.php?id=1103

    题目大意:链更新。链查询,求树链的最大子段和。(子段可以为空)

    解题思路

    将所有Query离线存储,并且注明哪个是更新,哪个是查询。

    Tarjan离线处理中,记录每个结点的前驱,p[v]=u。

    若更新,从u点回溯到LCA,从v点回溯到LCA,逐个修改。

    若查询,将u点回溯到LCA,LCA,v点回溯到LCA的倒序拼成一个序列,求最大子段和。

    值得注意的是,子段和全为负值的时候,ans=max(0,ans),即不要任何插线板(原题意思不明)。

    #include "cstdio"
    #include "cstring"
    #include "vector"
    #include "algorithm"
    using namespace std;
    #define maxn 100005
    #define inf 0x3f3f3f3f
    int head[maxn],qhead[maxn],lag[maxn],kth[maxn],tot1,tot2,f[maxn],vis[maxn],ancestor[maxn],p[maxn],s1[maxn],s2[maxn];
    bool isUpdate[maxn];
    struct Edge
    {
        int to,next;
    }e[maxn*2];
    struct Query
    {
        int from,to,next,idx,c;
    }q[maxn*2];
    void addedge(int u,int v)
    {
        e[tot1].to=v;
        e[tot1].next=head[u];
        head[u]=tot1++;
    }
    void addquery(int u,int v,int idx,int c=inf)
    {
        q[tot2].from=u;
        q[tot2].to=v;
        q[tot2].next=qhead[u];
        q[tot2].idx=idx;
        if(c!=inf) q[tot2].c=c;
        qhead[u]=tot2++;
    }
    int find(int x) {return x!=f[x]?f[x]=find(f[x]):x;}
    void Union(int u,int v)
    {
        u=find(u),v=find(v);
        if(u!=v) f[v]=u;
    }
    void LCA(int u)
    {
        vis[u]=true;
        f[u]=u;
        for(int i=head[u];i!=-1;i=e[i].next)
        {
            int v=e[i].to;
            if(!vis[v])
            {
                p[v]=u;
                LCA(v);
                Union(u,v);
            }
        }
        for(int i=qhead[u];i!=-1;i=q[i].next)
        {
            int v=q[i].to;
            if(vis[v]) ancestor[q[i].idx]=find(v);
            //or storage e[i].lca=e[i^1].lca=find(v)
        }
    }
    int sum(int num)
    {
        s2[0]=s1[0];
        int Max=s2[0];
        for(int i=1; i<num; i++)
        {
            if(s2[i-1]>0) s2[i]=s2[i-1]+s1[i];
            else s2[i]=s1[i];
            if(s2[i]>Max) Max=s2[i];
        }
        return max(0,Max);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T,n,m,u,v,c,cmd,qcnt=0;
        scanf("%d",&n);
        tot1=tot2=0;
        memset(head,-1,sizeof(head));
        memset(qhead,-1,sizeof(qhead));
        memset(vis,0,sizeof(vis));
        memset(isUpdate,0,sizeof(isUpdate));
        for(int i=1;i<=n;i++) scanf("%d",&lag[i]);
        for(int i=0; i<n-1; i++)
        {
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
        }
        scanf("%d",&m);
        for(int i=0; i<m; i++)
        {
            scanf("%d",&cmd);
            if(cmd==2)
            {
                scanf("%d%d%d",&u,&v,&c);
                addquery(u,v,i,c);
                addquery(v,u,i,c);
                isUpdate[i]=true;
            }
            else
            {
                scanf("%d%d",&u,&v);
                addquery(u,v,i);
                addquery(v,u,i);
            }
        }
        LCA(1);
        vector<int> ans;
        for(int i=0; i<tot2; i=i+2)
        {
            int u=q[i].from,v=q[i].to,idx=q[i].idx;
            int ed=ancestor[idx],cnt=0;
            if(isUpdate[qcnt])
            {
                int c=q[i].c;
                while(u!=ed) lag[u]=c,u=p[u];
                lag[ed]=c;
                while(v!=ed) lag[v]=c,v=p[v];
            }
            else
            {
                while(u!=ed) s1[cnt++]=lag[u],u=p[u];
                s1[cnt++]=lag[ed];
                vector<int> rev;
                while(v!=ed) rev.push_back(lag[v]),v=p[v];
                for(int j=rev.size()-1; j>=0; j--) s1[cnt++]=rev[j];
                int x=sum(cnt);
                ans.push_back(x);
            }
            qcnt++;
        }
        for(int i=0;i<ans.size()-1;i++) printf("%d ",ans[i]);
        printf("%d
    ",ans[ans.size()-1]);
    }
  • 相关阅读:
    机器视觉-halcon学习笔记1
    c#桌面窗体软件【学习笔记】
    Csharp学习笔记 重载
    unity学习笔记——第一人称
    Csharp学习笔记_kita (第二天)namespace
    try ,catch ,finally执行流程
    开发之统一异常处理
    git开发日常使用总结
    mysql5.7绿色版配置以及找不到 mysql服务问题解决
    正则表达式,将数据库字段转换为驼峰式
  • 原文地址:https://www.cnblogs.com/neopenx/p/4503066.html
Copyright © 2011-2022 走看看