4515: [Sdoi2016]游戏

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 351  Solved: 157
[Submit][Status][Discuss]

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 进行操作,输出一行一个数,表示他能够选择的最小的数字

Sample Input

3 5
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

123456789123456789
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 游戏的更多相关文章

  1. [luogu3676] 小清新数据结构题 [树链剖分+线段树]

    题面 传送门 思路 本来以为这道题可以LCT维护子树信息直接做的,后来发现这样会因为splay形态改变影响子树权值平方和,是splay本身的局限性导致的 所以只能另辟蹊径 首先,我们考虑询问点都在1的 ...

  2. BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树

    题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...

  3. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  4. 【bzoj4127】Abs 树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  5. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  6. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  7. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  8. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  9. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  10. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

随机推荐

  1. oracle 字符串切割成结果集方法

    oracle字符串切割几种方式 方法一: SELECT COLUMN_VALUE FROM TABLE(SYS.ODCIVARCHAR2LIST('1','2','3','4','5')); 方法二: ...

  2. ZOJ 3903 Ant(公式推导)

    这个公式推导过程是看的这位大牛的http://blog.csdn.net/bigbigship/article/details/49123643 扩展欧几里德求模的逆元方法: #include < ...

  3. AndroidManifest.xml--android系统权限定义

    1. 系统编译结束自动生成的java类,描述系统所有定义的权限 out/target/common/R/android/Manifest.java 2. 权限检查方法 frameworks/base/ ...

  4. Android开发---支付宝功能接口(支付功能)(转载!)

    最近在做一个关于购物商城的项目,项目里面付款这块我选的是调用支付宝的接口,因为用的人比较多. 在网上搜索了以下,有很多这方面的教程,但大部分教程过于陈旧,而且描述的过于简单.而且支付宝提供的接口一直在 ...

  5. Pomelo实现最简单的通信-egret。

    昨天因为需要开始学习Pomelo 做H5游戏的服务端. 因为个人学习习惯,我从来不适合去跟着文档看.一般我直接是看下大概的API,但是Pomelo的API全部都是英文的. 昨天我就告诉自己用一下午时间 ...

  6. java中的继承要点

    java的一大特性既是:继承. 1.因为有了一个子类继承了一个父类,才有了后面的多态. 2.类的继承,不要为了节省代码,为了继承而继承,把那个没有任何相关的类链接在一起,继承必须用在 is a,就是例 ...

  7. 【转载】【挖掘Treap的潜力】

    原帖: http://fanhq666.blog.163.com/blog/static/819434262011021105212299/ 你的Treap能支持以下操作吗?1.区间增减 2.区间求最 ...

  8. Linux nohup命令详解

    nohup命令及其输出文件                                                                                       ...

  9. underscorejs-shuffle学习

    2.21 shuffle 2.21.1 语法 _.shuffle(list) 2.21.2 说明 返回一个随机乱序的list副本数组, 使用 Fisher-Yates shuffle 来进行随机乱序. ...

  10. js四舍五入的bug和方法

    简单来说js使用原生toFixed(x)截取小数的时候会有误差,出现在比如var o = 0.3303;o.toFixed(3);//0.330 toFixed(x)本来也是一个获取四舍五入的截取方法 ...