【SDOI2016】bzoj4515 游戏

2023-11-07 19:48
文章标签 游戏 sdoi2016 bzoj4515

本文主要是介绍【SDOI2016】bzoj4515 游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description Alice 和 Bob 在玩一个游戏。 游戏在一棵有 n 个点的树上进行。最初,每个点上都只有一个数字,那个数字是
123456789123456789。 有时,Alice 会选择一条从 s 到 t
的路径,在这条路径上的每一个点上都添加一个数字。对于路径上的一个点 r, 若 r 与 s 的距离是 dis,那么 Alice 在点 r
上添加的数字是 a×dis+b。有时,Bob 会选择一条从 s 到 t 的路径。 他需要先从这条路径上选择一个点,再从那个点上选择一个数字。
Bob 选择的数字越小越好,但大量的数字让 Bob 眼花缭乱。Bob 需要你帮他找出他能够选择的最小的数字。 Input 第一行两个数字
n、m,表示树的点数和进行的操作数。 接下来 n−1 行,每行三个数字 u、v、w,表示树上有一条连接 u、v 的边,长度是 w。 接下来
m 行。每行第一个数字是 1 或 2。 若第一个数是 1,表示 Alice 进行操作,接下来四个数字 s、t、a、b。 若第一个数是
2,表示 Bob 进行操作,接下来四个数字 s、t。 Output

每当 Bob 进行操作,输出一行一个数,表示他能够选择的最小的数字

首先考虑序列上的问题,操作包括插入线段和询问区间最低点。用线段树来维护,线段树的每个节点存放一条线段和最优值。插入新线段的时候,先和普通的线段树区间修改一样找到要修改的位置,如果当前线段完全优直接换掉,完全劣直接舍去。否则根据图像可以发现,这两个线段一定有一个覆盖了一半多的区间【也就是在中点更优的那个】。把它放在这个节点,另外一个递归进入对应子树修改。在这个过程中顺便维护最优值。询问的时候就和普通的线段树一样了,但是注意这里不是简单的区间合并,在每个节点都要用当前线段更新答案。
放在树上也一样,只需要剖分一下。对于修改 (s,t,a,b) 在LCA点 u 处拆成两条链,分别是(s,u):y=adis[x]+adis[s]+b (t,u):y=adis[x]+adis[s]2adis[u]+b ,其中 dis[i] 表示 i 到根的距离。把dis[x]看成线段的横坐标就行了。因为边权是正的,一段链上的 dis 值一定是递增的。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
const LL oo=123456789123456789LL;
const int maxn=100010;
int rd()
{int x=0,f=1;char c=getchar();while (c<'0'||c>'9'){if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
struct Segment
{LL k,b;LL cal(LL x){return k*x+b;}
}low[2000010];
int fir[maxn],ne[2*maxn],to[2*maxn],w[2*maxn],
size[maxn],pos[maxn],top[maxn],fa[maxn][20],son[maxn],dep[maxn],
n,q,clo,lim;
LL dis[maxn],d2[maxn],mn[2000010];
int cmp(Segment s1,Segment s2,LL x)
{return s1.cal(x)<s2.cal(x);
}
void add(int num,int u,int v,int x)
{ne[num]=fir[u];fir[u]=num;to[num]=v;w[num]=x;
}
void dfs1(int u)
{int v;size[u]=1;for (int i=fir[u];i;i=ne[i])if ((v=to[i])!=fa[u][0]){fa[v][0]=u;dep[v]=dep[u]+1;dis[v]=dis[u]+w[i];dfs1(v);size[u]+=size[v];if (!son[u]||size[v]>size[son[u]]) son[u]=v;}
}
void dfs2(int u)
{int v;pos[u]=++clo;if (son[u]){top[son[u]]=top[u];dfs2(son[u]);}for (int i=fir[u];i;i=ne[i])if ((v=to[i])!=fa[u][0]&&v!=son[u]){top[v]=v;dfs2(v);}
}
int lca(int u,int v)
{if (dep[u]<dep[v]) swap(u,v);for (int k=lim;k>=0;k--)if (dep[u]-(1<<k)>=dep[v])u=fa[u][k];if (u==v) return u;for (int k=lim;k>=0;k--)if (fa[u][k]!=fa[v][k]){u=fa[u][k];v=fa[v][k];}return fa[u][0];
}
void build(int p,int L,int R)
{low[p]=(Segment){0,oo};mn[p]=oo;if (L<R){int mid=L+R>>1;build(p<<1,L,mid);build(p<<1|1,mid+1,R);}
}
void init()
{int u,v,x;n=rd();q=rd();for (int i=1;i<n;i++){u=rd();v=rd();x=rd();add(i<<1,u,v,x);add(i<<1|1,v,u,x);}dep[1]=1;dfs1(1);top[1]=1;dfs2(1);for (int i=1;i<=n;i++) d2[pos[i]]=dis[i];for (int k=1;(1<<k)<=n;k++) lim=k;for (int k=1;k<=lim;k++)for (int i=1;i<=n;i++)fa[i][k]=fa[fa[i][k-1]][k-1];build(1,1,n);
}
void down(int p,int L,int R,Segment s1)
{mn[p]=min(mn[p],min(s1.cal(d2[L]),s1.cal(d2[R])));if (L==R){if (cmp(s1,low[p],d2[L])) low[p]=s1;return;}int mid=L+R>>1,cl,cr,cm;cl=cmp(s1,low[p],d2[L]);cr=cmp(s1,low[p],d2[R]);cm=cmp(s1,low[p],d2[mid]);if (cl==cr){if (cl) low[p]=s1;}else{if (cm){if (cl) down(p<<1|1,mid+1,R,low[p]);else down(p<<1,L,mid,low[p]);low[p]=s1;}else{if (cl) down(p<<1,L,mid,s1);else down(p<<1|1,mid+1,R,s1);}}
}
void modify(int p,int L,int R,int l,int r,Segment s1)
{mn[p]=min(mn[p],min(s1.cal(d2[max(L,l)]),s1.cal(d2[min(R,r)])));if (l<=L&&R<=r){down(p,L,R,s1);return;}int mid=L+R>>1;if (l<=mid) modify(p<<1,L,mid,l,r,s1);if (r>mid) modify(p<<1|1,mid+1,R,l,r,s1);
}
void Modify(int v,int u,Segment s1)
{while (top[v]!=top[u]){modify(1,1,n,pos[top[v]],pos[v],s1);v=fa[top[v]][0];}modify(1,1,n,pos[u],pos[v],s1);
}
LL query(int p,int L,int R,int l,int r)
{if (l<=L&&R<=r) return mn[p];int mid=L+R>>1;LL ans=oo;if (l<=mid) ans=min(ans,query(p<<1,L,mid,l,r));if (r>mid) ans=min(ans,query(p<<1|1,mid+1,R,l,r));ans=min(ans,low[p].cal(d2[max(l,L)]));ans=min(ans,low[p].cal(d2[min(r,R)]));return ans;
}
LL Query(int u,int v)
{LL ret=oo;while (top[u]!=top[v]){if (dep[top[u]]<dep[top[v]]) swap(u,v);ret=min(ret,query(1,1,n,pos[top[u]],pos[u]));u=fa[top[u]][0];}if (dep[u]<dep[v]) swap(u,v);ret=min(ret,query(1,1,n,pos[v],pos[u]));return ret;
}
void solve()
{int opt,s,t,a,b,u;opt=rd();if (opt==1){s=rd();t=rd();a=rd();b=rd();u=lca(s,t);Modify(s,u,(Segment){-a,a*dis[s]+b});Modify(t,u,(Segment){a,a*dis[s]-2*a*dis[u]+b});}else{s=rd();t=rd();printf("%lld\n",Query(s,t));}
}
int main()
{/*freopen("menci_game.in","r",stdin);freopen("menci_game.out","w",stdout);*/init();while (q--) solve();
}

这篇关于【SDOI2016】bzoj4515 游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/365890

相关文章

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @

国产游戏行业的崛起与挑战:技术创新引领未来

国产游戏行业的崛起与挑战:技术创新引领未来 近年来,国产游戏行业蓬勃发展,技术水平不断提升,许多优秀作品在国际市场上崭露头角。从画面渲染到物理引擎,从AI技术到服务器架构,国产游戏已实现质的飞跃。然而,面对全球游戏市场的激烈竞争,国产游戏技术仍然面临诸多挑战。本文将探讨这些挑战,并展望未来的机遇,深入分析IT技术的创新将如何推动行业发展。 国产游戏技术现状 国产游戏在画面渲染、物理引擎、AI

第四次北漂----挣个独立游戏的素材钱

第四次北漂,在智联招聘上,有个小公司主动和我联系。面试了下,决定入职了,osg/osgearth的。月薪两万一。 大跌眼镜的是,我入职后,第一天的工作内容就是接手他的工作,三天后他就离职了。 我之所以考虑入职,是因为 1,该公司有恒歌科技的freex平台源码,可以学学,对以前不懂的解解惑。 2,挣点素材钱,看看张亮002的视频,他用了6000多,在虚幻商城买的吸血鬼游戏相关的素材,可以玩两年。我

nyoj 1038 纸牌游戏

poj 的一道改编题,说是翻译题更恰当,因为只是小幅度改动。 一道模拟题,代码掌控能力比较好,思维逻辑清晰的话就能AC。 代码如下: #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node{char c[5];int rk;char da[5];int nu

如果出一个名叫白神话悟空的游戏

最近黑神话由于与原著不符引起了原著派的争议。 所以我在摸鱼的时候想到如果游科或者某个别的公司“痛改前非”不夹带私货完全复刻吴承恩百回版剧情制作一个“重走西游路”的游戏,会有一个什么样的销量?(设定为原著派已经多方渠道认证,此游戏的确没有夹带私货,绝大部分复刻了原著剧情) 游戏玩法我想了几类 超长线性有岔路蜈蚣形状地图,蜈蚣的腿部是探索区域和支线,重走西游路线,开篇就是开始取经前唐玄宗御弟cg

《黑暗之魂2:原罪学者》是什么类型的游戏 《黑暗之魂》可以在苹果Mac电脑上玩吗?

在宏大的世界观游戏中,《黑暗之魂2:原罪学者》脱颖而出,以其探索性和挑战性征服了全球玩家的心灵。下面我们来看看《黑暗之魂2:原罪学者》是什么类型的游戏,《黑暗之魂2:原罪学者》可以在苹果电脑玩吗的相关内容。 一、《黑暗之魂2:原罪学者》是什么类型的游戏 《黑暗之魂2:原罪学者》作为《黑暗之魂2》的增强版和重制版,是一款FromSoftware制作、BANDAI NAMCO和FromSoft

简单取石子游戏~博弈

很坑爹的小游戏,至于怎么坑爹,嘎嘎~自己研究去吧~! #include<stdio.h>#include<windows.h>#include<iostream>#include<string.h>#include<time.h>using namespace std;void Loc(int x,int y);/*定位光标*/void Welcome(); /*创建欢迎界面*/

黑神话:悟空》增加草地绘制距离MOD使游戏场景看起来更加广阔与自然,增强了游戏的沉浸式体验

《黑神话:悟空》增加草地绘制距离MOD为玩家提供了一种全新的视觉体验,通过扩展游戏中草地的绘制距离,增加了场景的深度和真实感。该MOD通过增加草地的绘制距离,使游戏场景看起来更加广阔与自然,增强了游戏的沉浸式体验。 增加草地绘制距离MOD安装 1、在%userprofile%AppDataLocalb1SavedConfigWindows目录下找到Engine.ini文件。 2、使用记事本编辑