cf1110F 离线+树上操作+线段树区间更新
自己搞的算法超时了。。但是思路没什么问题:用线段树维护每个点到叶子节点的距离即可
/*
线段树维护区间最小值,每次向下访问,就把访问到的点对应的区间段减去边权
到另一颗子树访问时,向上回溯时加上减去的边权即可;
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 500050
#define INF 0x3f3f3f3f3f3f3f3f
struct Query{
int x,l,r,id;
bool operator<(const Query &y)const{return x<y.x;}
}Q[maxn];
int q,n,fa[maxn],r[maxn],leaf[maxn];
ll dep[maxn],w[maxn],ans[maxn]; /*线段树部分*/
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
ll Min[maxn<<],add[maxn<<];
inline void pushup(int rt){Min[rt]=min(Min[rt<<],Min[rt<<|])+add[rt];} void build(int l,int r,int rt){
add[rt]=;
if(l==r){Min[rt]=leaf[l]?dep[l]:INF;return;}//不是叶子节点就是无限大
int m=l+r>>;
build(lson);
build(rson);
pushup(rt);
}
void Add(int L,int R,int l,int r,int rt,int val){
if(L<=l && R>=r){
add[rt]+=val;Min[rt]+=val;return;
}
int m=l+r>>;
if(L<=m) Add(L,R,lson,val);
if(R>m) Add(L,R,rson,val);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt){
if(L<=l && R>=r)return Min[rt];
int m=l+r>>;
ll res=INF;
if(L<=m)res=min(res,query(L,R,lson));
if(R>m)res=min(res,query(L,R,rson));
return res+add[rt];
} int main(){
cin>>n>>q;
memset(leaf,,sizeof leaf);
for(int i=;i<=n;i++)r[i]=i;
for(int i=;i<=n;i++){
cin>>fa[i]>>w[i];
leaf[fa[i]]=;
dep[i]=dep[fa[i]]+w[i];
}
for(int i=n;i>=;i--)
r[fa[i]]=max(r[fa[i]],r[i]);
for(int i=;i<q;i++)
cin>>Q[i].x>>Q[i].l>>Q[i].r,Q[i].id=i;
sort(Q,Q+q); build(,n,);
int x=,qi=;//从根开始遍历
ll offset=;//用来记录回溯的
while(){
while(Q[qi].x==x && qi<q){
ans[Q[qi].id]=query(Q[qi].l,Q[qi].r,,n,)+offset;
++qi;
}
if(x<n){
int y=x+;
while(x!=fa[y]){
Add(x,r[x],,n,,*w[x]);
offset-=w[x]; x=fa[x];
}
x=y;
Add(x,r[x],,n,,-*w[x]);
offset+=w[x];
}
else break;
}
for(int i=;i<q;i++)printf("%lld\n",ans[i]);
}
这是cf上的代码
#include<bits/stdc++.h>
#define maxn 1000005
#define F first
#define S second
using namespace std;
typedef long long ll;
const ll INF=1e18;
typedef pair<ll,ll> pi;
typedef pair<int,pi> pii;
vector <pi> h[maxn];
vector <pii> q[maxn];
ll ans[maxn],a[maxn],dep[maxn],st[maxn*],add[maxn*];
int n,m,Q,id,l[maxn],r[maxn]; void build(int o,int l,int r){
if (l==r) st[o]=a[l];
else {
int m=l+((r-l)>>);
build(o<<,l,m);
build((o<<)|,m+,r);
st[o]=min(st[o<<],st[(o<<)|]);
}
} void pushup(int o){
st[o]=min(st[o<<],st[o<<|]);
} void pushdown(int o,int l,int r){
if (add[o]){
add[o<<]+=add[o];
add[o<<|]+=add[o];
int m=l+((r-l)>>);
st[o<<]+=add[o];
st[o<<|]+=add[o];
add[o]=;
}
} void update(int o,int l,int r,int ql,int qr,ll addv){
if (ql<=l&&qr>=r) {
add[o]+=addv;
st[o]+=addv;
return;
}
pushdown(o,l,r);
int m=l+((r-l)>>);
if (ql<=m) update(o<<,l,m,ql,qr,addv);
if (qr>=m+) update(o<<|,m+,r,ql,qr,addv);
pushup(o);
} ll query(int o,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return st[o];
pushdown(o,l,r);
int m=l+((r-l)>>);
ll ans=INF;
if (ql<=m) ans=min(ans,query(o<<,l,m,ql,qr));
if (qr>=m+) ans=min(ans,query(o<<|,m+,r,ql,qr));
return ans;
} void dfs0(int u){
++id; assert(u==id);
l[u]=id;
if (!h[u].size()) a[u]=dep[u]; else a[u]=INF;
for (int i=;i<h[u].size();i++){
int v=h[u][i].F;
dep[v]=dep[u]+h[u][i].S;
dfs0(v);
}
r[u]=id;
} void dfs(int u){
for (int i=;i<q[u].size();i++) ans[q[u][i].F]=query(,,n,q[u][i].S.F,q[u][i].S.S)+dep[u];
for (int i=;i<h[u].size();i++){
int v=h[u][i].F;
update(,,n,l[v],r[v],-h[u][i].S*);
dfs(v);
update(,,n,l[v],r[v],h[u][i].S*);
}
} int main(){
cin >> n >> Q;
for (int i=;i<=n;i++){
ll u,v;
scanf("%I64d%I64d",&u,&v);
h[u].push_back((pi){i,v});
}
for (int i=;i<=Q;i++){
int u,v,w;
scanf("%d%d%d",&w,&u,&v);
q[w].push_back((pii){i,(pi){u,v}});
}
dfs0();
build(,,n);
dfs();
for (int i=;i<=Q;i++) printf("%I64d\n",ans[i]);
return ;
}
cf1110F 离线+树上操作+线段树区间更新的更多相关文章
- hdu 3966(树链剖分+线段树区间更新)
传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...
- hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新
#1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...
- HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...
- HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...
- HDU5039--Hilarity DFS序+线段树区间更新 14年北京网络赛
题意:n个点的树,每个条边权值为0或者1, q次操作 Q 路径边权抑或和为1的点对数, (u, v)(v, u)算2个. M i修改第i条边的权值 如果是0则变成1, 否则变成0 作法: 我们可以求出 ...
- hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...
- POJ 3468:A Simple Problem with Integers(线段树区间更新模板)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 141093 ...
- ZOJ 1610 Count the Color(线段树区间更新)
描述Painting some colored segments on a line, some previously painted segments may be covered by some ...
- POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】
任意门:http://poj.org/problem?id=2528 Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total S ...
随机推荐
- linux scanf函数%d后加空白
参考链接: https://bbs.csdn.net/topics/390389059 关键点: scanf()中空白字符(包括/n,space)会使scanf()函数在读操作中略去输入中的零个或者一 ...
- 下载最新的glibc库并临时使用,而不污染原有系统环境
以下参考了文中提到的博文,那篇博文其中有他安装时报错的内容,以及如何解决的,特别是报错2,值得学习借鉴 另外升级glibc,这篇文章有补充https://blog.csdn.net/fzuzhangh ...
- python 07
1.文件操作: f=open(...) 是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码很明显是操作系统说了算了 操作系统会用自己的默认编码去打开文件,在windows ...
- java语言什么时候诞生的?
java语言什么时候诞生的?创始人是谁?何时发布的? Java编程语言是sun Microsystems公司JamesGosling在1990年创建的1995年公布于世
- Django学习手册 - 创建Django工程项目以及APP
前置步骤: 下载python,django 并且安装好 python 解释器以及django模块. 整体步骤阐述: 创建django工程项目 步骤一:进入安装的python目录 步骤二:输入创建工程的 ...
- Css - 三大特性
css - 三大特性 1.层叠性 如果通过两个相同选择器设置了同一个元素的某个相同的css属性,按照css相同属性的出现顺序,后面的样式会覆盖前面的样式 2.继承性 祖先元素的关于文本的样式会遗传给后 ...
- tmux 简单介绍
不定期更新. 虽然一直很抵制使用linux,尤其是服务器那种无界面的东东,但是没办法还是得用.平时连接上服务器后每次要执行一个新的命令都得开一个新窗口重新连接服务器,不仅麻烦,而且有的时候服务器或者我 ...
- C# 事务 四种事务隔离级别
http://www.zsythink.net/archives/1233 不同隔离级别的问题 脏读(Dirty Read) 一个事务处理过程里读取了另一个未提交的事务中的数据 例子: 当一个事务 ...
- EM算法(坐标上升算法)
原文地址:https://www.cnblogs.com/to-creat/p/6075322.html 机器学习十大算法之一:EM算法.能评得上十大之一,让人听起来觉得挺NB的.什么是NB啊,我们一 ...
- CF1139A Even Substrings
题目地址:CF1139A Even Substrings 一个数是偶数等价于其最后一位为偶数(2/4/6/8/0) 从左往右扫一遍,如果一个数是奇数则直接跳过,偶数则加上它对答案的贡献 这里的贡献应该 ...