洛谷P3261 [JLOI2015]城池攻占(左偏树)

本文深入探讨了一种基于小根堆和DFS的骑士攻城算法,通过将骑士和城池抽象为点,利用堆操作和树遍历实现骑士对城池的攻占过程,详细解释了如何更新骑士和城池的状态,以及如何处理骑士死亡和城池被攻占的情况。

传送门

 

每一个城市代表的点开一个小根堆,把每一个骑士合并到它开始攻占的城池所代表的点上

然后开始dfs,每一次把子树里那些还活着的骑士合并上来

然后再考虑当前点的堆,一直pop直到骑士全死光或者剩下的骑士的攻击力都大于等于当前城池的生命值,同时维护城池和骑士的答案

然后修改的话在堆顶打一个标记,需要的时候下传即可

 1 //minamoto
 2 #include<bits/stdc++.h>
 3 #define ll long long
 4 using namespace std;
 5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 6 char buf[1<<21],*p1=buf,*p2=buf;
 7 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
 8 inline ll read(){
 9     #define num ch-'0'
10     char ch;bool flag=0;ll res;
11     while(!isdigit(ch=getc()))
12     (ch=='-')&&(flag=true);
13     for(res=num;isdigit(ch=getc());res=res*10+num);
14     (flag)&&(res=-res);
15     #undef num
16     return res;
17 }
18 char sr[1<<21],z[20];int K=-1,Z;
19 inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
20 inline void print(int x){
21     if(K>1<<20)Ot();if(x<0)sr[++K]=45,x=-x;
22     while(z[++Z]=x%10+48,x/=10);
23     while(sr[++K]=z[Z],--Z);sr[++K]='\n';
24 }
25 const int N=3e5+5;
26 int head[N],Next[N],ver[N],tot;
27 inline void add_edge(int u,int v){
28     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
29 }
30 int L[N],R[N],rt[N],d[N],ans1[N],ans2[N],dep[N],c[N],n,m;
31 ll add[N],mul[N],v[N],h[N],val[N];bool fl[N];
32 inline void ppd(int p,ll m,ll a){
33     if(p){
34         v[p]*=m,v[p]+=a;
35         mul[p]*=m,add[p]*=m,add[p]+=a;
36     }
37 }
38 inline void pd(int p){
39     ppd(L[p],mul[p],add[p]),ppd(R[p],mul[p],add[p]);
40     mul[p]=1,add[p]=0;
41 }
42 int merge(int x,int y){
43     if(!x||!y) return x+y;
44     pd(x),pd(y);
45     if(v[x]>v[y]) swap(x,y);
46     R[x]=merge(R[x],y);
47     if(d[L[x]]<d[R[x]]) swap(L[x],R[x]);
48     d[x]=d[R[x]]+1;return x;
49 }
50 void dfs(int u,int fa){
51     dep[u]=dep[fa]+1;
52     for(int i=head[u];i;i=Next[i]){int v=ver[i];dfs(v,u),rt[u]=merge(rt[u],rt[v]);}
53     while(rt[u]&&v[rt[u]]<h[u]){
54         pd(rt[u]);++ans1[u],ans2[rt[u]]=dep[c[rt[u]]]-dep[u];
55         rt[u]=merge(L[rt[u]],R[rt[u]]);
56     }
57     fl[u]?ppd(rt[u],val[u],0):ppd(rt[u],1,val[u]);
58 }
59 int main(){
60 //    freopen("testdata.in","r",stdin);
61     n=read(),m=read();
62     for(int i=1;i<=n;++i) h[i]=read();
63     for(int i=2;i<=n;++i){
64         int fa=read();fl[i]=read(),val[i]=read();
65         add_edge(fa,i);
66     }
67     for(int i=1;i<=m;++i){
68         v[i]=read(),c[i]=read();
69         mul[i]=1;
70         rt[c[i]]=merge(rt[c[i]],i);
71     }
72     dfs(1,0);
73     while(rt[1]) pd(rt[1]),ans2[rt[1]]=dep[c[rt[1]]],rt[1]=merge(L[rt[1]],R[rt[1]]);
74     for(int i=1;i<=n;++i) print(ans1[i]);
75     for(int i=1;i<=m;++i) print(ans2[i]);
76     Ot();
77     return 0;
78 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9806327.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值