51Nod 1199 Money out of Thin Air (树链剖分+线段树)
第1行:2个数N, M,N为节点的数量,M为操作的数量(1 <= N, M <= 50000)。
第2 - N行:每行描述一个节点N[i]的信息,第2行对应编号为1的节点,第N行对应编号为N - 1的节点。具体内容为:每行2个数P[i], W[i]。P[i]为当前节点的父节点的编号,W[i]为当前节点的权值。(0 <= W[i] <= 10^5, P[i] < i)
第N + 1 - N + M行:每行表示一个操作,S x y z或A x y z,(0 <= y, z <= 10^5)。
输出共N行,每行1个数W[i],表示经过M次后,编号为0 - N - 1的节点的权值。
4 3
0 10
0 10
1 2
S 0 1 1
A 0 20 1
S 3 2 1
2
11
11
3 思路:
很简单的一道树链剖分+线段树,写起来麻烦点。。代码量有点大,一不小心就打错了。找半天。。 实现代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid ll m = (l + r) >> 1
const ll M = 7e5+;
struct node{
ll to,next;
}e[M];
ll n,m,cnt1,cnt,a[M];
ll sum[M<<],lazy[M<<],son[M],fa[M],head[M],siz[M],top[M],dep[M],tid[M],rk[M],mx[M];
void add(ll u,ll v){
e[++cnt1].to = v;e[cnt1].next = head[u];head[u] = cnt1;
e[++cnt1].to = u;e[cnt1].next = head[v];head[v] = cnt1;
} void dfs1(ll u,ll faz,ll deep){
dep[u] = deep;
fa[u] = faz;
siz[u] = ;
for(ll i = head[u];i;i=e[i].next){
ll v = e[i].to;
if(v != fa[u]){
dfs1(v,u,deep+);
siz[u] += siz[v];
if(son[u] == -||siz[v] > siz[son[u]])
son[u] = v;
}
}
} void dfs2(ll u,ll t){
top[u] = t;
mx[u] = cnt;
tid[u] = cnt;
rk[cnt] = u;
cnt++;
if(son[u] == -) return;
dfs2(son[u],t),mx[u] = max(mx[u],mx[son[u]]);
for(ll i = head[u];i;i = e[i].next){
ll v = e[i].to;
if(v != son[u]&&v != fa[u])
dfs2(v,v),mx[u]=max(mx[u],mx[v]);
}
} void scan_d ( ll& x , char c = , ll flag = ) {
while ( ( c = getchar () ) != '-' && ( c < '' || c > '' ) ) ;
if ( c == '-' ) flag = , x = ;
else x = c - '' ;
while ( ( c = getchar () ) >= '' && c <= '' ) x = x * + c - '' ;
if ( flag ) x = -x ;
} void pushup(ll rt){
sum[rt] = sum[rt<<] + sum[rt<<|];
} void build(ll l,ll r,ll rt){
if(l == r){
sum[rt] = a[rk[l]];
//cout<<"l: "<<l<<" sum: "<<sum[rt]<<" al: "<<rk[l]<<endl;
return ;
}
mid;
build(lson);
build(rson);
pushup(rt);
} void update(ll p,ll c,ll l,ll r,ll rt){
if(l == r){
sum[rt] += c;
return ;
}
mid;
if(p <= m) update(p,c,lson);
else update(p,c,rson);
pushup(rt);
} void pushdown(ll l,ll r,ll rt){
if(lazy[rt]){
mid;
lazy[rt<<]+=lazy[rt];
lazy[rt<<|]+=lazy[rt];
sum[rt<<]+=lazy[rt]*(m-l+);
sum[rt<<|]+=lazy[rt]*(r-m);
lazy[rt] = ;
}
} ll query(ll L,ll R,ll l,ll r,ll rt){
if(L <= l&&R >= r){
return sum[rt];
}
//cout<<l<<" "<<r<<endl;
pushdown(l,r,rt);
mid;
ll ret = ;
if(L <= m) ret += query(L,R,lson);
if(R > m) ret += query(L,R,rson);
return ret;
} void update1(ll L,ll R,ll c,ll l,ll r,ll rt){
if(l == r){
sum[rt]+=c;
return ;
}
if(L <= l&&R >= r){
sum[rt]+=c*(r-l+);
lazy[rt]+=c;
return ;
}
mid;
pushdown(l,r,rt);
if(L <= m) update1(L,R,c,lson);
if(R > m) update1(L,R,c,rson);
pushup(rt);
} ll query1(ll p,ll l,ll r,ll rt){
if(l == r) return sum[rt];
pushdown(l,r,rt);
mid;
if(p <= m) return query1(p,lson);
else return query1(p,rson);
} int main()
{
ios::sync_with_stdio();
cin.tie(); cout.tie();
ll u,w;
cin>>n>>m;
a[] = ;
memset(son,-,sizeof(son));
for(ll i = ;i < n;i ++){
cin>>u>>w;
add(u,i);a[i]=w;
}
dfs1(,-,); dfs2(,); build(,n-,);
char op;
ll x,y,z;
while(m--){
cin>>op>>x>>y>>z;
if(op == 'A'){
ll ans = query(tid[x],mx[x],,n-,);
double num = ans*1.0/(mx[x]-tid[x]+);
if(num < y) update1(tid[x],mx[x],z,,n-,);
}
else{
ll ans = query1(tid[x],,n-,);
if(ans < y) update(tid[x],z,,n-,);
}
}
for(ll i = ;i < n;i ++){
cout<<query1(tid[i],,n-,)<<endl;;
}
return ;
}
51Nod 1199 Money out of Thin Air (树链剖分+线段树)的更多相关文章
- 【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 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
随机推荐
- 【C/C++】1~20的阶乘之和
一. 前情 能点进这篇文章的,想必也已经知道了C语言和C++语言,以及阶乘的定义,所以在此不赘述了.SUM(1!~20!)这个问题是我在大一学C语言时的一个小题,最近又要把编译器装回来,所以装完之 ...
- Linux服务-openssh
目录 1. 使用 SSH 访问远程命令行 1.1 OpenSSH 简介 1.2 SSH 版本 1.3 SSH 认证方式 1.4 openSSH 的工作模式 1.5 Secure Shell 示例 1. ...
- 20155204《网络对抗》Exp9 Web安全基础实践
20155204<网络对抗>Exp9 Web安全基础实践 一.基础问题回答 SQL注入攻击原理,如何防御? 原理: SQL注入即是指web应用程序对用户输入数据的合法性没有判断,攻击者可以 ...
- 20155232《网络对抗》Exp8 Web基础
20155232<网络对抗>Exp 8 Web基础 一.实践内容 (1).Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编 ...
- 20155233 《网络对抗》 Exp8 Web基础
实验内容 Web前端HTML Web前端javascipt Web后端:MySQL基础:正常安装.启动MySQL,建库.创建用户.修改密码.建表 Web后端:编写PHP网页,连接数据库,进行用户认证 ...
- 蓝牙inquiry流程之Advertising Report
setting 界面开始搜索的时候,通常也会同时进行le scan,这一点在inquiry流程之命令下发中已经讲述.此篇文章主要是分析一下对于controller 搜索到的广播包的处理.这里以Andr ...
- centos 6.5 搭建开源堡垒机 Teleport 遇到的问题解决
几款开源的堡垒机 下面进行 teleport 的安装: https://docs.tp4a.com/install/#11 异常1:libc.so.6: version `GLIBC_2.14' no ...
- javascript典型bug——错误的闭包
昨天QT给我的一个功能提了一个bug.大概意思就是说,一段在不同位置都会被调用的代码,在A处被调用的时候,似乎会对其他调用的地方产生影响. 我仔细debug了半天,终于找到了原因.简化过的代码如下: ...
- Jmeter(二十三)_插件扩展
Jmeter插件管理器 安装插件的方法有两种,一种是传统的方式,即官网下载,本地配置,重启jmeter.现在有一种快捷的方法可以自定义安装插件-插件管理器 JMeter 插件管理器的使用方法很简单:不 ...
- Inno Setup脚本
某天夜晚一场狂风暴雨,由于办公室座位旁的窗户没关,笔记本电脑泡了一夜水,无法开机,无奈送修,里面的大量资料也不知道会不会丢失. is的脚本只有重新写了,重新研究了一下检测程序是否正在运行的判断方法,另 ...