P2590 [ZJOI2008]树的统计

操作:

I. CHANGE u t : 把结点u的权值改为t

II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值

III. QSUM u v: 询问从点u到点v的路径上的节点的权值和

标签:树剖+线段树 模板题。

转化一下题意:

操作1:单点修改。

操作2:利用树剖求LCA的过程求经过的点的权值的最大值。

操作3:利用树剖求LCA的过程累加经过的点的权值之和。

Code:

#include<cstdio>
#include<iostream>
#include<string>
#define ri register int
using namespace std;

const int MAXN=60020;
int n,m,q,u[MAXN],v[MAXN],w[MAXN],fst[MAXN],nxt[MAXN],num,t;
int fa[MAXN],deep[MAXN],siz[MAXN],son[MAXN],cmax[MAXN],top[MAXN],dfn[MAXN],rk[MAXN],cur,a[MAXN];
int l[MAXN<<2],r[MAXN<<2],maxn[MAXN<<2],sum[MAXN<<2];
string ss;

void dfs1(int x,int father,int dep)
{
    fa[x]=father,deep[x]=dep,siz[x]=1;
    for(ri k=fst[x];k>0;k=nxt[k])
        if(v[k]!=father)
        {
            dfs1(v[k],x,dep+1);
            if(siz[v[k]]>cmax[x])	cmax[x]=siz[v[k]],son[x]=v[k];
            siz[x]+=siz[v[k]];
        }
}

void dfs2(int x,int anc)
{
    top[x]=anc,dfn[x]=++cur,rk[cur]=x,a[cur]=w[x];
    if(son[x]!=0)	dfs2(son[x],anc);
    for(ri k=fst[x];k>0;k=nxt[k])
        if(v[k]!=fa[x]&&v[k]!=son[x])	dfs2(v[k],v[k]);
}

void pushup(int p)
{
    sum[p]=sum[p <<1]+sum[p <<1|1];
    maxn[p]=max(maxn[p <<1],maxn[p <<1|1]);	
}

void build(int p,int lft,int rit)
{
    l[p]=lft,r[p]=rit;
    if(lft==rit)	{ sum[p]=a[lft]; maxn[p]=a[lft]; return; }
    int mid=(lft+rit)>>1;
    build(p <<1,lft,mid);
    build(p <<1|1,mid+1,rit);
    pushup(p);
}

void update(int p,int pla,int k)
{
    if(l[p]==pla&&r[p]==pla)
    {
        sum[p]=k,maxn[p]=k;
        return; 
    }
    if(pla<=r[p <<1])    update(p <<1,pla,k);
    if(l[p <<1|1]<=pla)    update(p <<1|1,pla,k);
    pushup(p);
}

int qmax(int p,int lft,int rit)
{
    if(lft<=l[p]&&r[p]<=rit)	return maxn[p];
    int ans=-1e9;
    if(lft<=r[p <<1])    ans=qmax(p <<1,lft,rit);
    if(l[p <<1|1]<=rit)	   ans=max(ans,qmax(p <<1|1,lft,rit));
    return ans;	
}

int LCAmax(int x,int y)
{
    int ans=-1e9;
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]])	swap(x,y);
        ans=max(ans,qmax(1,dfn[top[x]],dfn[x]));
        x=fa[top[x]];
    }
    if(deep[x]<deep[y])	swap(x,y);
    ans=max(ans,qmax(1,dfn[y],dfn[x]));
    return ans;	
}

int qsum(int p,int lft,int rit)
{
    if(lft<=l[p]&&r[p]<=rit)	return sum[p];
    int ans=0;
    if(lft<=r[p <<1])    ans=qsum(p <<1,lft,rit);
    if(l[p <<1|1]<=rit)	   ans+=qsum(p <<1|1,lft,rit);
    return ans;
}

int LCAsum(int x,int y)
{
    int ans=0;
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]])	swap(x,y);
        ans+=qsum(1,dfn[top[x]],dfn[x]);
        x=fa[top[x]];
    }
    if(deep[x]<deep[y])	swap(x,y);
    ans+=qsum(1,dfn[y],dfn[x]);
    return ans;
}

int main()
{
    scanf("%d",&n);
    m=(n-1)<<1;
    for(ri i=1;i<=m;i+=2)
    {
        scanf("%d%d",&u[i],&v[i]);
        nxt[i]=fst[u[i]],fst[u[i]]=i;
        u[i+1]=v[i],v[i+1]=u[i];
        nxt[i+1]=fst[u[i+1]],fst[u[i+1]]=i+1;
    }
    for(ri i=1;i<=n;i++)	scanf("%d",&w[i]);
    dfs1(1,1,0);
    dfs2(1,1);
    build(1,1,n);
    scanf("%d",&q);
    for(int i=1;i<=q;i++)
    {
        cin>>ss>>num>>t;
        if(ss=="CHANGE")    update(1,dfn[num],t);
        if(ss=="QMAX")    cout<<LCAmax(num,t)<<'\n';
        if(ss=="QSUM")    cout<<LCAsum(num,t)<<'\n';
    }
    return 0;
}

 

需求响应动态冰蓄冷系统与需求响应策略的优化研究(Matlab代码实现)内容概要:本文围绕需求响应动态冰蓄冷系统及其优化策略展开研究,结合Matlab代码实现,探讨了在电力需求侧管理背景下,冰蓄冷系统如何通过优化运行策略参与需求响应,以实现削峰填谷、降低用电成本和提升能源利用效率的目标。研究内容包括系统建模、负荷预测、优化算法设计(如智能优化算法)以及多场景仿真验证,重点分析不同需求响应机制下系统的经济性和运行特性,并通过Matlab编程实现模型求解与结果可视化,为实际工程应用提供理论支持和技术路径。; 适合人群:具备一定电力系统、能源工程或自动化背景的研究生、科研人员及从事综合能源系统优化工作的工程师;熟悉Matlab编程且对需求响应、储能优化等领域感兴趣的技术人员。; 使用场景及目标:①用于高校科研中关于冰蓄冷系统与需求响应协同优化的课题研究;②支撑企业开展楼宇能源管理系统、智慧园区调度平台的设计与仿真;③为政策制定者评估需求响应措施的有效性提供量化分析工具。; 阅读建议:建议读者结合文中Matlab代码逐段理解模型构建与算法实现过程,重点关注目标函数设定、约束条件处理及优化结果分析部分,同时可拓展应用其他智能算法进行对比实验,加深对系统优化机制的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值