数据结构(树链剖分,线段树):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的路径中的所有边的颜色翻转. 操作 ...
随机推荐
- oracle 字符串切割成结果集方法
oracle字符串切割几种方式 方法一: SELECT COLUMN_VALUE FROM TABLE(SYS.ODCIVARCHAR2LIST('1','2','3','4','5')); 方法二: ...
- ZOJ 3903 Ant(公式推导)
这个公式推导过程是看的这位大牛的http://blog.csdn.net/bigbigship/article/details/49123643 扩展欧几里德求模的逆元方法: #include < ...
- AndroidManifest.xml--android系统权限定义
1. 系统编译结束自动生成的java类,描述系统所有定义的权限 out/target/common/R/android/Manifest.java 2. 权限检查方法 frameworks/base/ ...
- Android开发---支付宝功能接口(支付功能)(转载!)
最近在做一个关于购物商城的项目,项目里面付款这块我选的是调用支付宝的接口,因为用的人比较多. 在网上搜索了以下,有很多这方面的教程,但大部分教程过于陈旧,而且描述的过于简单.而且支付宝提供的接口一直在 ...
- Pomelo实现最简单的通信-egret。
昨天因为需要开始学习Pomelo 做H5游戏的服务端. 因为个人学习习惯,我从来不适合去跟着文档看.一般我直接是看下大概的API,但是Pomelo的API全部都是英文的. 昨天我就告诉自己用一下午时间 ...
- java中的继承要点
java的一大特性既是:继承. 1.因为有了一个子类继承了一个父类,才有了后面的多态. 2.类的继承,不要为了节省代码,为了继承而继承,把那个没有任何相关的类链接在一起,继承必须用在 is a,就是例 ...
- 【转载】【挖掘Treap的潜力】
原帖: http://fanhq666.blog.163.com/blog/static/819434262011021105212299/ 你的Treap能支持以下操作吗?1.区间增减 2.区间求最 ...
- Linux nohup命令详解
nohup命令及其输出文件 ...
- underscorejs-shuffle学习
2.21 shuffle 2.21.1 语法 _.shuffle(list) 2.21.2 说明 返回一个随机乱序的list副本数组, 使用 Fisher-Yates shuffle 来进行随机乱序. ...
- js四舍五入的bug和方法
简单来说js使用原生toFixed(x)截取小数的时候会有误差,出现在比如var o = 0.3303;o.toFixed(3);//0.330 toFixed(x)本来也是一个获取四舍五入的截取方法 ...