【BZOJ4515】[Sdoi2016]游戏 树链剖分+线段树
【BZOJ4515】[Sdoi2016]游戏
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
题解:很神的线段树~
一个操作相当于加入一条线段,一个询问相当于求一段区间的最小值。那么我们线段树的每个节点都要维护这些东西:左右端点的dis值,区间中最小的数,以及这段区间中最优的线段。但是如果又新来了一条线段呢?需要分类讨论了:
如果旧线段在左右端点的取值都比新线段优,则新线段显然没用;如果新线段在左右断电的取值都比旧线段有,则旧线段显然没用;否则呢?递归下去更新即可。
就这么完事了?嗯。时间复杂度?那就再来一个log呗,$O(nlog^3_n)$。(再来一个log你会更强)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lson x<<1
#define rson x<<1|1
using namespace std;
const int maxn=100010;
typedef long long ll;
const ll inf=123456789123456789ll;
int n,m,cnt;
int to[maxn<<1],next[maxn<<1],val[maxn<<1],head[maxn],dep[maxn],siz[maxn],son[maxn],top[maxn],fa[maxn];
int p[maxn],q[maxn];
ll sa[maxn<<2],sb[maxn<<2],sl[maxn<<2],sr[maxn<<2],sn[maxn<<2],dis[maxn];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
inline void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[x])
{
fa[to[i]]=x,dep[to[i]]=dep[x]+1,dis[to[i]]=dis[x]+val[i],dfs1(to[i]),siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
}
}
void dfs2(int x,int tp)
{
top[x]=tp,p[x]=++q[0],q[q[0]]=x;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[x]&&to[i]!=son[x]) dfs2(to[i],to[i]);
}
void build(int l,int r,int x)
{
sn[x]=sb[x]=inf;
if(l==r)
{
sl[x]=sr[x]=dis[q[l]];
return ;
}
int mid=(l+r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
sl[x]=sl[lson],sr[x]=sr[rson];
}
void updata(int l,int r,int x,int a,int b,ll c,ll d)
{
int mid=(l+r)>>1;
if(a<=l&&r<=b)
{
if(sl[x]*sa[x]+sb[x]>sl[x]*c+d&&sr[x]*sa[x]+sb[x]>sr[x]*c+d) sa[x]=c,sb[x]=d;
else if(sl[x]*sa[x]+sb[x]>sl[x]*c+d||sr[x]*sa[x]+sb[x]>sr[x]*c+d)
updata(l,mid,lson,a,b,c,d),updata(mid+1,r,rson,a,b,c,d);
sn[x]=min(sn[x],min(sl[x]*c+d,sr[x]*c+d));
if(l!=r) sn[x]=min(sn[x],min(sn[lson],sn[rson]));
return ;
}
if(a<=mid) updata(l,mid,lson,a,b,c,d);
if(b>mid) updata(mid+1,r,rson,a,b,c,d);
sn[x]=min(sn[x],min(sn[lson],sn[rson]));
return ;
}
ll query(int l,int r,int x,int a,int b)
{
if(a<=l&&r<=b) return sn[x];
ll ret=min(dis[q[a]]*sa[x]+sb[x],dis[q[b]]*sa[x]+sb[x]);
int mid=(l+r)>>1;
if(a<=mid) ret=min(ret,query(l,mid,lson,a,min(b,mid)));
if(b>mid) ret=min(ret,query(mid+1,r,rson,max(a,mid+1),b));
return ret;
}
inline int lca(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]]) x=fa[top[x]];
else y=fa[top[y]];
}
if(dep[x]>dep[y]) return y;
return x;
}
inline void modify()
{
int x=rd(),y=rd();
ll a=rd(),b=rd(),c=dis[x]*a+b,d=(dis[x]-2*dis[lca(x,y)])*a+b;
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]]) updata(1,n,1,p[top[x]],p[x],-a,c),x=fa[top[x]];
else updata(1,n,1,p[top[y]],p[y],a,d),y=fa[top[y]];
}
if(dep[x]<dep[y]) updata(1,n,1,p[x],p[y],a,d);
else updata(1,n,1,p[y],p[x],-a,c);
}
inline void ask()
{
int x=rd(),y=rd();
ll ret=inf;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret=min(ret,query(1,n,1,p[top[x]],p[x])),x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ret=min(ret,query(1,n,1,p[x],p[y]));
printf("%lld\n",ret);
}
int main()
{
n=rd(),m=rd();
int i,a,b,c;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),c=rd(),add(a,b,c),add(b,a,c);
dep[1]=1,dfs1(1),dfs2(1,1);
build(1,n,1);
for(i=1;i<=m;i++)
{
if(rd()==1) modify();
else ask();
}
return 0;
}//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
【BZOJ4515】[Sdoi2016]游戏 树链剖分+线段树的更多相关文章
- BZOJ2819Nim——树链剖分+线段树+Nim游戏
题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...
- 【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的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
随机推荐
- ruby send respond_to
http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html http://galeki.is-progr ...
- 原生javascript星级评分
写个最简单的原生js的星级评分: <div id="rank" class="pingfen"> <ul> <li>< ...
- 关于Unity中stretch的分开使用、预制体、Scroll View的UI节点
一.上次讲的菊花的四个花瓣,只讲了四个花瓣和在一起的时候的作用,现在是分开的菊花的四个花瓣的作用 1.创建一个Canvas2.对Canvas进行初始化3.创建一个Image的UI节点作为Canvas的 ...
- Python版本,pip版本手动管理
http://blog.csdn.net/jiandanjinxin/article/details/53175121
- nginx报错:No package erlang available
问题 yum install erlang 报错:No package erlang available 同样的,如果我们在安装nginx的时候出现"No package nginx ava ...
- [转] C# mysql 事务回滚
什么是数据库事务 数据库事务是指作为单个逻辑工作单元执行的一系列操作. 设想网上购物的一次交易,其付款过程至少包括以下几步数据库操作: · 更新客户所购商品的库存信息 · 保存客户付款信息--可能包括 ...
- 【AngularJS】AngularJS整合Springmvc、Mybatis环境搭建
近期想学习AngularJS的使用,网上搜了一圈后,折腾了半天解决bug后,成功使用AngularJS整合Springmvc.Spring.Mybatis搭建了一个开发环境.(这里Spring使用的版 ...
- ZABBIX API简介及使用
API简介 Zabbix API开始扮演着越来越重要的角色,尤其是在集成第三方软件和自动化日常任务时.很难想象管理数千台服务器而没有自动化是多么的困难.Zabbix API为批量操作.第三方软件集成以 ...
- Spring-Condition设置
为了满足不同条件下生成更为合适的bean,可以使用condition配置其条件.假如有一个bean,id为magicBean,只有当其具有magic属性时才生成,方法如下: javaConfig模式: ...
- 关于Bundle
1. 黄色的文件夹,打包的时候,不会建立目录,主要保存程序文件 - 素材不允许重名 2. 蓝色的文件夹,打包的时候,会建立目录,可以分目录的存储素材文件 - 素材可以重名 - 游戏的场景,backgr ...