[ZJOI2018]历史,洛谷P4338,类LCT维护

本文探讨了一种针对有根树的轻重边切换优化算法,旨在通过动态调整访问顺序,最大化轻重边的切换次数。算法首先确定静态最优解,随后通过类似于LCT的维护策略,使用Splay树动态更新树状结构,以应对访问次数的动态变化,确保高效求解。

正题

      题目大意,大致就是给出一棵有根数,给出每个点access的次数,要你安排顺序,求轻重边切换最多多少次,动态加次数.

      第一步其实还挺好想的,思考一下如何静态做,发现相当于对于每一个节点,就是让各个子树的权值和 和 自己的access次数互插,使得相邻两个不同的个数越多越好,这个东西想一想就可以知道答案是\min(2*(n-x),n-1),其中x是最大的个数,具体怎么得来,可以直接分类讨论(x>n/2 x=n/2 x<n/2)三种情况,笔者不多赘述.

      第二步才是有意思的地方,我们可以在x>n/2时连实边,否则连虚边,然后用类似LCT一样维护实边构成的spaly.每次access实边的答案都不会变因为x,n都增加了,虚边可能会变成实边,也有可能将原来的实边断掉,分类讨论即可.这样每次跳虚边,子树权值和必定翻倍,那么总跳跃次数就是log ai总和.每次要进行一次splay,那么复杂度就是两个log.

 

#include<bits/stdc++.h>
#define ls son[x][0]
#define rs son[x][1]
using namespace std;

const int N=450010;
int n,m;
struct edge{
	int y,next;
}s[N<<1];
int first[N],len=0,fa[N],lazy[N],sta[N];
long long sum[N],val[N],S[N];
int son[N][2];
long long ans=0;

void ins(int x,int y){
	s[++len]=(edge){y,first[x]};first[x]=len;
	s[++len]=(edge){x,first[y]};first[y]=len;
}

bool nrt(int x){
	return !(son[fa[x]][0]!=x && son[fa[x]][1]!=x);
}

void update(int x){
	sum[x]=val[x]+S[x]+sum[ls]+sum[rs];
}

void dfs(int x){
	long long mmax=val[x];
	int p=0;
	for(int i=first[x];i!=0;i=s[i].next) if(s[i].y!=fa[x]){
		int y=s[i].y;fa[y]=x;dfs(y);
		S[x]+=sum[y];
		if(sum[y]>mmax) mmax=sum[y],p=y;
	}
	if(2*mmax>=val[x]+S[x]+1 && p) S[x]-=mmax,son[x][1]=p;
	update(x);
	ans+=min(sum[x]-1,2*(sum[x]-mmax));
}

void rotate(int x){
	int f=fa[x],ff=fa[f],w=(son[f][0]==x);
	fa[x]=ff;fa[f]=x;if(son[x][w]) fa[son[x][w]]=f;
	if(son[ff][0]==f) son[ff][0]=x;
	else if(son[ff][1]==f) son[ff][1]=x;
	son[f][1-w]=son[x][w];son[x][w]=f;
	update(f);update(x);
}

void splay(int x){
	while(nrt(x)){
		if(nrt(fa[x])){
			if((son[fa[x]][0]==x) ^ (son[fa[fa[x]]][0]==fa[x])) rotate(x);
			else rotate(fa[x]);
		}
		rotate(x);
	}
}

void access(int x,int t){
	splay(x);
	long long Sum=sum[x]-sum[ls];
	ans-=min(Sum-1,2*(Sum-max(sum[rs],val[x])));
	val[x]+=t;sum[x]+=t;Sum+=t;
	ans+=min(Sum-1,2*(Sum-max(sum[rs],val[x])));
	if(sum[rs]*2<Sum+1) S[x]+=sum[rs],rs=0;
	int last=x;x=fa[x];
	while(x){
		splay(x);
		Sum=sum[x]-sum[ls];
		ans-=min(Sum-1,2*(Sum-max(sum[rs],val[x])));
		sum[x]+=t;S[x]+=t;Sum+=t;
		ans+=min(Sum-1,2*(Sum-max(sum[last],max(val[x],sum[rs]))));
		if(sum[last]*2>=Sum+1) S[x]-=sum[last],S[x]+=sum[rs],rs=last;
		else if(sum[rs]*2<Sum+1) S[x]+=sum[rs],rs=0; 
		last=x;x=fa[x];
	}
}

int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&val[i]);
	int x,y;
	for(int i=1;i<n;i++) scanf("%d %d",&x,&y),ins(x,y);
	fa[1]=0;dfs(1);
	printf("%lld\n",ans);
	while(m--){
		scanf("%d %d",&x,&y);
		access(x,y);
		printf("%lld\n",ans);
	}
}

      

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值