hdu 6133 Army Formations

题意很迷,给一棵n个节点的树,每个节点有一个权值是这个节点完成其任务的时间。

比如第一个任务的权值是1,完成它将在第一秒,第二个任务的权值是2,完成前两个任务的时间是3秒。

现在问你完成任务的时间再加上罚时是多少,罚时是完成任务的时间再加上它开始做任务的时间。比如一个任务权值是3,从第四秒开始做,那么完成它的时间加罚时是7秒。

现在问你以每个节点为根的子树完成所有节点的任务的最小时间(加罚时)是多少。

 

可以想最后的时间必定是所有任务的时间加上罚时,那么罚时越少最后的总时间就越小。

所有在一棵子树里,我们把所有节点的任务排序,按从小到大执行任务这样的罚时越少。

 

因为一个根节点下每颗子树间的任务没有交集,所以只能进行启发式合并。

每颗子树的任务不用排序,可以用树状数组维护。

考虑贡献,从小到大开始放,那么小的任务值必定会给比他任务值大的节点都带来他的时间作为罚时的贡献。

那么每加入新的一个节点,我们询问比它大的节点有多少个都乘上它的权值,再询问比它小的节点的总权值是多少。那么总的贡献就算完了。

 

 

 

代码:

 

 

#include <bits/stdc++.h>
using namespace std;
const int M = 1e5+7;
typedef long long ll;
int head[M],cnt,n,_,tot;
int sz[M],son[M],pos[M];
ll csum[M],ans[M],val[M],cnum[M],a[M],tmp;
struct edge{
    int v,next;
}e[M<<1];
void init(){
    cnt=0;memset(head,-1,sizeof(head));
    tmp=0;memset(ans,0,sizeof(ans));
}
void add(int u,int v){
    e[++cnt].v=v;e[cnt].next=head[u];
    head[u]=cnt;
}
void update(int x,ll y,ll *c){
    for(;x<=tot;x+=x&(-x)){
        c[x]+=y;
    }
}
ll query(int x,ll *c){
    ll k=0;
    for(;x;x-=x&(-x)){
        k+=c[x];
    }
    return k;
}
void dfs(int u,int fa){
    csum[u]=cnum[u]=0;
    sz[u]=1;
    son[u]=-1;
    for(int i=head[u];~i;i=e[i].next){
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,u);
        sz[u]+=sz[v];
        if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v;
    }
    return ;
}
void add_node(int u){
    tmp+=(query(tot,cnum)-query(pos[u],cnum))*val[u]+val[u];//加上把这个点放入的时间再加上给比他大的点带来的罚时
    tmp+=query(pos[u],csum);//加上比这个点小的点给这个点带来的罚时
    update(pos[u],val[u],csum);//这个点带来的贡献加入罚时数组
    update(pos[u],1,cnum);//这个能接受比它小的后面的点带来的罚时
}
void del_node(int u){//删除节点
    update(pos[u],-val[u],csum);//先更新树状数组再更新答案因为多加的答案是还未加入此节点时多算的贡献
    update(pos[u],-1,cnum);
    tmp-=((query(tot,cnum)-query(pos[u],cnum))*val[u]+val[u]);
    tmp-=query(pos[u],csum);
}
void del_tree(int u,int fa){//删除子树
    del_node(u);
    for(int i=head[u];~i;i=e[i].next){
        int v=e[i].v;
        if(v==fa) continue;
        del_tree(v,u);
    }
}
void add_tree(int u,int fa){//加入子树
    add_node(u);
    for(int i=head[u];~i;i=e[i].next){
        int v=e[i].v;
        if(v==fa) continue;
        add_tree(v,u);
    }
}
void dfs1(int u,int fa){
    if(sz[u]==1){//如果是根节点
        add_node(u);
        ans[u]=val[u];
        return ;
    }
    for(int i=head[u];~i;i=e[i].next){
        int v=e[i].v;
        if(v==fa||v==son[u]) continue;
        dfs1(v,u);//寻找子树的答案
        del_tree(v,u);//将子树删除
    }
    dfs1(son[u],u);//找重儿子的答案
    for(int i=head[u];~i;i=e[i].next){
        int v=e[i].v;
        if(v==fa||v==son[u]) continue;
        add_tree(v,u);//将子树的答案加到根节点中
    }
    add_node(u);//将根节点加入
    ans[u]=tmp;
}
int main(){
    scanf("%d",&_);
    while(_--){
        init();//初始化
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);val[i]=a[i];
        }
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v);add(v,u);
        }
        dfs(1,-1);//找重儿子
        sort(a+1,a+n+1);//排序
        tot=unique(a+1,a+n+1)-a-1;//去重
        for(int i=1;i<=n;i++){
            pos[i]=lower_bound(a+1,a+tot+1,val[i])-a;//找到每个元素在去重数组中的位置
        }
        dfs1(1,-1);
        for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
        puts("");
    }
    return 0;
} 
View Code

 

转载于:https://www.cnblogs.com/LMissher/p/9537515.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
08-10
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值