SDOI 2016 游戏
树链剖分
线段树维护区间最小值,区间最大值
更新,对于每一个区间,找到当前区间的最小值的最大值,和要更新的值比较,如果比最大值还大,则此数对于以后的询问无任何贡献,直接返回即可,若有贡献,则一直递归到叶子节点,将最值全部更新
询问,直接询问区间最小值即可
/*Alice 和 Bob 在玩一个游戏。 游戏在一棵有 n 个点的树上进行。最初,每个点上都只有一个数字,那个数字是 123456789123456789。 有时,Alice 会选择一条从 s 到 t 的路径,在这条路径上的每一个点上都添加一个数字。对于路径上的一个点 r,若 r 与 s 的距离是 dis,那么 Alice 在点 r 上添加的数字是 a×dis+b。 有时,Bob 会选择一条从 s 到 t 的路径。他需要先从这条路径上选择一个点,再从那个点上选择一个数字。 Bob 选择的数字越小越好,但大量的数字让 Bob 眼花缭乱。Bob 需要你帮他找出他能够选择的最小的数字。 */ #include<bits/stdc++.h> #define ll long long #define inf 123456789123456789 #define maxn 100010 using namespace std; inline int read(){int s=0,f=1;char ch=getchar();for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())s=s*10+ch-'0';return s*f; } int n,m; int fa[maxn][18],dep[maxn],f[maxn]; struct edge{int to,next,w; }G[maxn<<1]; int tot,h[maxn]; void add(int x,int y,int z){tot++;G[tot].to=y;G[tot].next=h[x];G[tot].w=z;h[x]=tot; } int pos[maxn],sz,size[maxn],poz[maxn]; ll t[maxn<<2],dis[maxn],mx[maxn<<2]; void dfs(int x){for(int i=1;i<=17;++i)if(dep[x]<(1<<i))break;else fa[x][i]=fa[fa[x][i-1]][i-1];for(int i=h[x];i;i=G[i].next){int v=G[i].to;if(dep[v])continue;dep[v]=dep[x]+1;fa[v][0]=x;dis[v]=dis[x]+G[i].w;dfs(v);size[x]+=size[v];}size[x]++; } void dfs(int x,int ff){pos[x]=++sz;f[x]=ff;poz[sz]=x;int mx=0;for(int i=h[x];i;i=G[i].next)if(dep[G[i].to]>dep[x]&&size[G[i].to]>size[mx])mx=G[i].to;if(!mx)return;dfs(mx,ff);for(int i=h[x];i;i=G[i].next)if(dep[G[i].to]>dep[x]&&mx!=G[i].to)dfs(G[i].to,G[i].to); } int lca(int x,int y){if(dep[x]<dep[y])swap(x,y);int d=dep[x]-dep[y];for(int i=0;i<=17;++i)if(d&(1<<i))x=fa[x][i];if(x==y)return x;for(int i=17;i>=0;--i)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];if(x==y)return x;return fa[x][0]; } void build(int k,int l,int r){if(l==r){t[k]=inf;mx[k]=inf;return;}int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);t[k]=min(t[k<<1],t[k<<1|1]);mx[k]=max(mx[k<<1],mx[k<<1|1]); } void init(){n=read();m=read();for(int i=1;i<n;++i){int x=read(),y=read(),z=read();add(x,y,z);add(y,x,z);}dep[1]=1;dfs(1);dfs(1,1);build(1,1,n); } void work1(int k,int l,int r,int x,int y,ll a,ll b,ll d1,ll d2){if(mx[k]<=a*d1+b&&mx[k]<=a*d2+b)return;if(l==r){t[k]=a*d1+b,mx[k]=a*d1+b;return;}int mid=(l+r)>>1;if(y<=mid)work1(k<<1,l,mid,x,y,a,b,d1,d2);else if(x>mid)work1(k<<1|1,mid+1,r,x,y,a,b,d1,d2);else work1(k<<1,l,mid,x,mid,a,b,d1+dis[poz[y]]-dis[poz[mid]],d2),work1(k<<1|1,mid+1,r,mid+1,y,a,b,d1,d1+dis[poz[y]]-dis[poz[mid+1]]);t[k]=min(t[k<<1],t[k<<1|1]);mx[k]=max(mx[k<<1],mx[k<<1|1]); } void work2(int k,int l,int r,int x,int y,ll a,ll b,ll d1,ll d2){if(mx[k]<=a*d1+b&&mx[k]<=a*d2+b)return;if(l==r){t[k]=a*d1+b,mx[k]=a*d1+b;return;}int mid=(l+r)>>1;if(y<=mid)work2(k<<1,l,mid,x,y,a,b,d1,d2);else if(x>mid)work2(k<<1|1,mid+1,r,x,y,a,b,d1,d2);else work2(k<<1,l,mid,x,mid,a,b,d1,d1+dis[poz[mid]]-dis[poz[x]]),work2(k<<1|1,mid+1,r,mid+1,y,a,b,d1+dis[poz[mid+1]]-dis[poz[x]],d2);t[k]=min(t[k<<1],t[k<<1|1]);mx[k]=max(mx[k<<1],mx[k<<1|1]); } void work(int x,int y,ll a,ll b){int k=lca(x,y);int u=x;while(f[x]!=f[k]){work1(1,1,n,pos[f[x]],pos[x],a,b,dis[u]-dis[x],dis[u]-dis[f[x]]);x=fa[f[x]][0];}work1(1,1,n,pos[k],pos[x],a,b,dis[u]-dis[x],dis[u]-dis[k]);while(f[y]!=f[k]){work2(1,1,n,pos[f[y]],pos[y],a,b,dis[u]+dis[f[y]]-2*dis[k],dis[u]+dis[y]-2*dis[k]);y=fa[f[y]][0];}work2(1,1,n,pos[k],pos[y],a,b,dis[u]-dis[k],dis[u]+dis[y]-2*dis[k]); } ll ask(int k,int l,int r,int x,int y){if(x<=l&&r<=y)return t[k];int mid=(l+r)>>1;if(y<=mid)return ask(k<<1,l,mid,x,y);if(x>mid)return ask(k<<1|1,mid+1,r,x,y);return min(ask(k<<1,l,mid,x,y),ask(k<<1|1,mid+1,r,x,y)); } void work(int x,int y){int k=lca(x,y);ll ans=inf;while(f[x]!=f[k]){ans=min(ans,ask(1,1,n,pos[f[x]],pos[x]));x=fa[f[x]][0];}ans=min(ans,ask(1,1,n,pos[k],pos[x]));while(f[y]!=f[k]){ans=min(ans,ask(1,1,n,pos[f[y]],pos[y]));y=fa[f[y]][0];}ans=min(ans,ask(1,1,n,pos[k],pos[y]));printf("%lld\n",ans); } void work(){for(int i=1;i<=m;++i){int opt=read();if(opt==1){int s=read(),t=read(),a=read(),b=read();work(s,t,a,b);}else{int s=read(),t=read();work(s,t);}} } int main(){init();work();return 0; }
View Code
转载于:https://www.cnblogs.com/117208-/p/5383865.html
SDOI 2016 游戏相关推荐
- 台式计算机高配 2016,2016游戏笔记本电脑推荐 五款高配笔记本电脑【图文推荐】...
对于喜欢网游戏的朋友来说,对电脑配置的要求还是比较高的.配置好的电脑市场上也比较多,很多网友也不知道如何选择,那么下面来看看2016游戏 笔记本电脑 推荐吧,希望能够帮助您的选购. 2016游戏笔记本 ...
- 网易2016游戏技术岗在线编程题(一)
题目来源:牛客网-网易2016年研发工程师编程题. 1.小易的升级之路 小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段时间内,他将会依次遇见n个怪 ...
- 网易2016游戏技术岗在线编程题(二)
题目来源:牛客网-网易2016年研发工程师编程题二. 1. 奖学金 小v今年有n门课,每门都有考试,为了拿到奖学金,小v必须让自己的平均成绩至少为avg.每门课由平时成绩和考试成绩组成,满分为r.现在 ...
- [SDOI 2016]征途
Description 题库链接 将一个长度为 \(n\) 的正整数序列分为 \(m\) 段,问你这 \(m\) 段最小的方差 \(v\) 为多少.输出 \(v\times m^2\) . \(1\l ...
- 【SDOI 2016】征途
传送门 Problem 给出一个有 n n n 个数的序列 { a n } \{a_n\} {an},现要把它分成 m m m 段,设每段的权值为该段 a i a_i ai 之和,求出这 m m ...
- SDOI 2016 生成魔咒 题解
题目传送门 题目大意: 给出一个字符串,询问它的每一个前缀内包含多少个不同的子串. 题解 将字符一个一个加入到SAM里,每个新的字符的的贡献为 l e n ( x ) − l e n ( l i n ...
- 沉浸式ui设计_有助于沉浸的视频游戏UI —武器轮
沉浸式ui设计 Many action-adventure games rely on the feeling of thrills via bullets, fire, grenade, more ...
- 【游戏调研】梦幻花园——引领三消新模式
一.游戏简介 一款不仅仅面向核心消除用户的游戏 <梦幻花园>是一款三消类游戏,与传统消除游戏不同的是,这款三消与养成建造.剧情玩法结合在一起,玩家需要通关获得星星,消耗星星推进任务,装扮花 ...
- 2018 年 5 月
今天是 5 月 3 日,从今天开始每天打个卡,大概是晚上 8 点到 10 点之间更新,记录一天所学. 5 月 3 日 1.min-max 容斥 容斥应用在 min max 之间,有 $$\max S ...
最新文章
- iOS学习之路十三(动态调整UITableViewCell的高度)
- biomaRt包下载转录本信息
- svn cleanup failed–previous operation has not finished 解决方法
- 关于Android Service真正的完全详解,你需要知道的一切
- 下载服务器文件到本地
- 免费好用的web应用托管平台
- ejb 2.1 jboss_JBoss AS 8中的Java EE 7和EJB 3.2支持
- Java 8 LongAdders:管理并发计数器的正确方法
- spring整合logback
- spring 事务案例--转账
- python learning2.py
- 修改表字段长度的操作,对业务是否有影响?
- 微信小程序—连接MQTT
- 谷歌联网断网都可以玩的恐龙小游戏(内容有不死加速挂)
- [CSS揭秘]菱形图片
- Unity动画系统学习方向
- ih5学习笔记_事件对象
- 屏幕不光只看尺寸 各材质屏幕实战解析
- VC6 SP6下载地址
- Swagger2.0