[HAOI2015]树上操作(树链剖分)

树链剖分与线段树详解
本文详细解析了树链剖分和线段树的实现原理与应用,通过具体代码示例,展示了如何利用这两种数据结构解决复杂的数据查询与更新问题。文章深入浅出地介绍了树链剖分的基本概念、线段树的构建过程,以及两者结合使用的方法,为读者提供了丰富的编程技巧和算法优化思路。

原题

BZOJ
洛谷

Solution

直接很简单的树链剖分然后搞一个线段树维护一下就好了?

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#define ll long long
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
using namespace std;
inline int gi(){
    int sum=0,f=1;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-f;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
inline ll gl(){
    ll sum=0,f=1;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-f;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
const int maxn=500010;
ll old[maxn];int to[maxn<<1],nxt[maxn<<1],front[maxn],cnt;ll w[maxn];
int siz[maxn],fa[maxn],dep[maxn],son[maxn],top[maxn],b[maxn],n;
struct node{
    int l,r;ll add,val;
}tree[maxn<<4];
void Add(int u,int v){
    to[++cnt]=v;nxt[cnt]=front[u];front[u]=cnt;
}
void dfs1(int u,int f){
    siz[u]=1;fa[u]=f;dep[u]=dep[f]+1;
    for(int i=front[u];i;i=nxt[i]){
        int v=to[i];
        if(v!=fa[u]){
            dfs1(v,u);
            siz[u]+=siz[v];
            if(siz[v]>siz[son[u]])son[u]=v;
        }
    }
}
void dfs2(int u,int tp){
    top[u]=tp;b[u]=++cnt;w[cnt]=old[u];
    if(!son[u])return;
    dfs2(son[u],tp);
    for(int i=front[u];i;i=nxt[i]){
        int v=to[i];
        if(v!=son[u] && v!=fa[u])dfs2(v,v);
    }
}
void pushup(int o){
    tree[o].val=tree[o<<1].val+tree[o<<1|1].val;
}

void build(int o,int l,int r){
    tree[o].l=l;tree[o].r=r;tree[o].add=0;
    if(l==r){
        tree[o].val=w[l];
        return;
    }
    int mid=(l+r)>>1;
    build(o<<1,l,mid);build(o<<1|1,mid+1,r);
    pushup(o);
}
void pushdown(int o){
    if(tree[o].add){
        tree[o<<1].add+=tree[o].add;
        tree[o<<1|1].add+=tree[o].add;
        tree[o<<1].val+=tree[o].add*(tree[o<<1].r-tree[o<<1].l+1);
        tree[o<<1|1].val+=tree[o].add*(tree[o<<1|1].r-tree[o<<1|1].l+1);
        tree[o].add=0;
    }
}
void update(int o,int l,int r,int posl,int posr,ll k){
    if(posl<=l && r<=posr){
        tree[o].val+=k*(r-l+1);tree[o].add+=k;
        return;
    }
    pushdown(o);
    int mid=(l+r)>>1;
    if(mid>=posr)update(o<<1,l,mid,posl,posr,k);
    else if(mid<posl)update(o<<1|1,mid+1,r,posl,posr,k);
    else{
        update(o<<1,l,mid,posl,mid,k);
        update(o<<1|1,mid+1,r,mid+1,posr,k);
    }
    pushup(o);
}
ll query(int o,int l,int r,int posl,int posr){
    if(posl<=l && r<=posr)return tree[o].val;
    pushdown(o);
    int mid=(l+r)>>1;
    if(mid>=posr)return query(o<<1,l,mid,posl,posr);
    else if(mid<posl)return query(o<<1|1,mid+1,r,posl,posr);
    return query(o<<1,l,mid,posl,mid)+query(o<<1|1,mid+1,r,mid+1,posr);
}
ll Query(int u,int v){
    ll ans=0;
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        ans+=query(1,1,n,b[top[u]],b[u]);u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    return ans+query(1,1,n,b[u],b[v]);
}
int main(){
    int i,j,m,k;
    n=gi();m=gi();
    for(i=1;i<=n;i++)old[i]=gi();
    for(i=1;i<n;i++){
        int u=gi(),v=gi();
        Add(u,v);Add(v,u);
    }
    cnt=0;
    dfs1(1,1);dfs2(1,1);
    build(1,1,n);
    while(m--){
        int x,a,opt;cin>>opt>>x;
        if(opt==1){
            cin>>a;
            update(1,1,n,b[x],b[x],a);
        }
        else if(opt==2){
            cin>>a;
            update(1,1,n,b[x],b[x]+siz[x]-1,a);
        }
        else printf("%lld\n",Query(1,x));
    }
    return 0;
}

转载于:https://www.cnblogs.com/cjgjh/p/9833302.html

(1)求职者端(Web 前端) 岗位浏览与搜索: 智能推荐首页:基于 “专业背景 + 求职意向” 推荐匹配岗位(如 “计算机专业硕士” 优先推荐 “高校计算机教师岗”“实验员岗”),展示岗位核心信息(学校名称、岗位名称、薪资范围、截止日期)。 多条件筛选:支持按 “岗位类型(教学岗 / 科研岗 / 行政岗)、学历要求(硕士 / 博士)、地区(华北 / 华东等)、学校层次(985/211 / 双非)” 组合筛选,结果按 “匹配度 / 发布时间 / 薪资” 排序。 岗位详情页:展示 “岗位职责、任职要求、福利待遇、应聘流程、联系人信息”,提供 “收藏岗位、一键投递简历、查看该岗位竞争热度(如‘已有 230 人投递’)” 功能。 个人求职中心: 简历管理:支持创建多版本简历(如 “教学岗专用简历”“科研岗专用简历”),包含 “基本信息、教育经历、科研成果、教学经验、获奖情况” 等模块,支持 PDF 导出和在线编辑。 应聘跟踪:记录 “已投递岗位、简历状态(已接收 / 筛选中 / 面试通知 / 已录用)、截止日期提醒”,对 “3 天内即将截止的岗位” 自动推送提醒。 竞争分析:针对已投递岗位,展示 “求职者学历分布(博士占比 75%)、专业匹配度排名(你的匹配度 85 分,超过 80% 竞争者)”,辅助评估自身竞争力。 (2)高校招聘负责人端(Web 管理端) 岗位管理: 岗位发布:填写 “岗位名称、招聘人数、学历要求、专业方向、岗位职责、薪资范围、应聘方式” 等信息,支持上传 “岗位说明书附件”,设置 “自动截止日期” 和 “简历接收邮箱”。 批量操作:对 “已过期岗位” 进行批量下架,对 “热门岗位(投递量>100)” 设置 “自动置顶”,支持 “岗位信息批量导出(Excel 格式)”。 简历筛选: 智能初筛:系统自动对投递简历进行 “匹配度评分”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值