数据结构(树链剖分,线段树):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的路径中的所有边的颜色翻转. 操作 ...
随机推荐
- enter 默认搜索
onkeydown=" if(event.keyCode==13) Search(); "
- Shell - 文件运算符
文件运算符 文件运算符 描述 -b file 检测 file 是否为块设备文件 -c file 检测 file 是否为字符设备文件 -d file 检测 file 是否为目录 -e fil ...
- Eclipse代码自动填充.
在默认情况下,Eclipse只在程序员输入“.”并用ALT+/组合键强制调用编码提示功能 我们可以通过少量配置,让Eclipse更聪明,实现完全自动编码提示:1.在你的“工作空间”下找到下在文件.me ...
- 开发自己的cordova插件
如果还没有配置过cordova环境,首先要下载nodejs,(下载地址https://nodejs.org/)下载完毕安装. 控制台: 1.输入npm -v 确定是否装上了 2.输入sudo npm ...
- C# 线程间互相通信
C#线程间互相通信主要用到两个类:AutoResetEvent和ManualResetEvent. 一.AutoResetEvent AutoResetEvent 允许线程通过发信号互相通信,线程通过 ...
- 人人网FED CSS编码前端开发规范
文件相关规范 1.文件名必须由小写字母.数字.中划线-组成 2.文件必须用utf-8编码 3.文件引入可通过外联或内联方式引入: 3.1 外联方式:<link rel=”stylesheet” ...
- 马的遍历问题-回溯法应用-ACM
马的遍历问题 在n*m的棋盘中,马只能走“日” 字.马从位置(x,y)处出发,把棋盘的每一格都走一次,且只走一次.找出所有路径. 问题解的搜索空间? 棋盘的规模是n*m,是指行有n条边,列有m条边. ...
- phpstorm IDE编辑器使用手记
a.选项卡限制问题 突破打开的文件选项卡个数限制:默认安装后的phpstorm打开的文件个数是有限制的,默认是10个.也就是最多同时打开10个文件进行编辑. 超过10个就会自动关闭前面最先打开的文件. ...
- windows 下PHP 和 nginx配置
http://www.cnblogs.com/huayangmeng/archive/2011/06/15/2081337.html
- oracle常见为题汇总,以及一个简单数据连接操作工厂
本人软件环境:win8.1 64位操作系统,vs2013,安装好了与oracle数据库对应的客户端 连接oracle数据库.以及操作数据库 1.使用IIS建立网站,浏览网页时候,提示“ ...