数据结构(树链剖分,线段树):SDOI 2016 游戏
4515: [Sdoi2016]游戏
Time Limit: 40 Sec Memory Limit: 256 MB
Submit: 351 Solved: 157
[Submit][Status][Discuss]
Description
Input
Output
每当 Bob 进行操作,输出一行一个数,表示他能够选择的最小的数字
Sample Input
1 2 10
2 3 20
2 1 3
1 2 3 5 6
2 2 3
1 2 3 -5 -6
2 2 3
Sample Output
6
-106
HINT
n≤100000,m≤100000,∣a∣≤10000,0<=w,|b|<=10^9
李超线段树?
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
const long long INF=123456789123456789LL;
int n,Q,cnt;
int fir[maxn],nxt[maxn<<],to[maxn<<],val[maxn<<];
int dep[maxn],fa[maxn],sz[maxn],son[maxn];
long long dis[maxn];
void addedge(int a,int b,int v){
nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;val[cnt]=v;
} void DFS(int x){
sz[x]=;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa[x]){
fa[to[i]]=x;
dis[to[i]]=dis[x]+val[i];
dep[to[i]]=dep[x]+;
DFS(to[i]);
sz[x]+=sz[to[i]];
if(sz[son[x]]<sz[to[i]])
son[x]=to[i];
}
} int top[maxn],ID[maxn],rID[maxn],tot;
void DFS(int x,int tp){
ID[x]=++tot;rID[tot]=x;top[x]=tp;
if(son[x])DFS(son[x],tp);
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=son[x]&&to[i]!=fa[x])
DFS(to[i],to[i]);
} int Lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
} struct Node{
long long a,b;
Node(long long a_=,long long b_=INF){
a=a_;b=b_;
}
long long Val(int x){
return a*dis[rID[x]]+b;
}
int CmP(int l,int r,Node a){
if(Val(l)<=a.Val(l)&&Val(r)<=a.Val(r))return ;
if(Val(l)>=a.Val(l)&&Val(r)>=a.Val(r))return -;
return ;
}
}F[maxn<<];
long long Min[maxn<<]; void Build(int x,int l,int r){
Min[x]=INF;
if(l==r)return;
Build(x<<,l,(l+r)>>);
Build(x<<|,((l+r)>>)+,r);
} void Update(int x,int l,int r,int a,int b,Node p){
int mid=(l+r)>>;
Min[x]=min(Min[x],min(p.Val(max(a,l)),p.Val(min(b,r))));
if(l>=a&&r<=b){
int tmp=p.CmP(l,r,F[x]);
if(tmp==)F[x]=p;
if(tmp!=)return; tmp=p.CmP(l,mid,F[x]);
if(tmp!=)Update(x<<,l,mid,a,b,F[x]); tmp=p.CmP(mid+,r,F[x]);
if(tmp!=)Update(x<<|,mid+,r,a,b,F[x]);
}
if(l==r)return;
if(mid>=a)Update(x<<,l,mid,a,b,p);
if(mid<b)Update(x<<|,mid+,r,a,b,p);
} void Modify(int x,int y,Node p){
while(top[x]!=top[y]){
Update(,,n,ID[top[x]],ID[x],p);
x=fa[top[x]];
}
Update(,,n,ID[y],ID[x],p);
} long long Query(int x,int l,int r,int a,int b){
if(l>=a&&r<=b)return Min[x];
int mid=(l+r)>>;
long long ret=min(F[x].Val(max(l,a)),F[x].Val(min(r,b)));
if(mid>=a)ret=min(ret,Query(x<<,l,mid,a,b));
if(mid<b)ret=min(ret,Query(x<<|,mid+,r,a,b));
return ret;
} long long Solve(int x,int y){
long long ret=INF;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ret=min(ret,Query(,,n,ID[top[x]],ID[x]));
x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
return min(ret,Query(,,n,ID[y],ID[x]));
} int main(){
#ifndef ONLINE_JUDGE
freopen("menci_game.in","r",stdin);
freopen("menci_game.out","w",stdout);
#endif
scanf("%d%d",&n,&Q);
for(int i=,x,y,w;i<n;i++){
scanf("%d%d%d",&x,&y,&w);
addedge(x,y,w);addedge(y,x,w);
} DFS();
DFS(,);
Build(,,n); int type,s,t,lca;
long long a,b;
while(Q--){
scanf("%d",&type);
if(type==){
scanf("%d%d%lld%lld",&s,&t,&a,&b);
lca=Lca(s,t);
Modify(s,lca,Node(-a,a*dis[s]+b));
Modify(t,lca,Node(a,a*(dis[s]-*dis[lca])+b));
}
else{
scanf("%d%d",&s,&t);
printf("%lld\n",Solve(s,t));
}
}
return ;
}
数据结构(树链剖分,线段树):SDOI 2016 游戏的更多相关文章
- [luogu3676] 小清新数据结构题 [树链剖分+线段树]
题面 传送门 思路 本来以为这道题可以LCT维护子树信息直接做的,后来发现这样会因为splay形态改变影响子树权值平方和,是splay本身的局限性导致的 所以只能另辟蹊径 首先,我们考虑询问点都在1的 ...
- BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...
- BZOJ4127Abs——树链剖分+线段树
题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...
- 【bzoj4127】Abs 树链剖分+线段树
题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
随机推荐
- java开发webservice的几种方式(转载)
webservice的应用已经越来越广泛了,下面介绍几种在Java体系中开发webservice的方式,相当于做个记录. 1.Axis2方式 Axis是apache下一个开源的webservice开发 ...
- C# 里窗体里(windows form)怎么播放音乐
在.NET的winform里面,没有托管的音乐播放器,API只能播放WAV格式,对于MP3等形式的音频文件,就要依赖于 MediaPlayer里,嘿嘿 使用的方法: 在toolbox上点右键,选择“选 ...
- c# 连接oracle 读取数据
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- javascript基础学习(九)
javascript之基本包装类型 学习要点: 基本包装类型概述 Boolean类型 Number类型 String类型 一.基本包装类型概述 为了便于操作基本类型值,提供了3种特殊的引用类型:Boo ...
- java中的继承要点
java的一大特性既是:继承. 1.因为有了一个子类继承了一个父类,才有了后面的多态. 2.类的继承,不要为了节省代码,为了继承而继承,把那个没有任何相关的类链接在一起,继承必须用在 is a,就是例 ...
- 【SPOJ839】最优标号
[题目描述] 给你一张无向图G(V,E).每个顶点都有一个标号,它是一个[0,2^31-1]内的整数.不同的顶点可能会有相同的标号. 对每条边(u,v),我们定义其费用cost(u,v)为u的标号与v ...
- 常见的mongodb可视化工具
一.MongoVue 1.MongoVUE是一款比较好用的MongoDB客户端工具,可以为大家提供一个高度.简洁可用的MongoDB管理界面. 2.通过MongoVUE,用户可以用树形.表格及bj ...
- 如何用DOS 链接mysql
1.Ctrl+R 打开DOS窗口 2.键入 cd\ 回车进入C盘根目录 3.进入mysql bin目录下 操作mysql命令 4.输入连接数据库命令 mysql -hlocalhost -uroot ...
- php学习之基础语法
这些语法都是在学习视频的过程中整理出来的,有些很简单的语法可能就没有整理了,只是记录了自己看来比较重要的语法内容. 1.变量使用 $ 声明 ,变量区分大小写 变量的类型: 4种标量类 ...
- Insert Interval 面试题leetcode.
刚开始做这个题的时候绕了好大的圈,对问题的分析不全面,没能考虑所有情况,做的很纠结.后来看了下大神的做法很受启发,改了改代码,最终提交了. public static ArrayList<Int ...