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 ...
随机推荐
- jQuery的extend和fn.extend理解
参考网址:http://www.cnblogs.com/yuanyuan/archive/2011/02/23/1963287.html http://www.cnblogs.com/xuxiuyu/ ...
- 代码段:js表单提交检测
市面上当然有很多成型的框架,比如jquery的validation插件各种吧.现在工作地,由于前端童鞋也没用这些个插件.根据业务的要求,自己就在代码里写了个简单的表单提交的检测代码(php的也写了一个 ...
- 【本地服务器】json-server搭建本地https服务器(windows)
(一)用json-server搭建简单的服务器 (搭建出来的服务器地址为localhost:3000) 1.新建Mockjson文件夹,进入该文件夹目录,运行命令 npm install -g jso ...
- WC 2019 游记 - 败者之低语
败者之低语 WC 2019 游记 Day -1 看了一圈PKU和THU的题,感觉图像识别真有意思... 感觉非常讲道理,pku还是比thu简单一点的... 听说高二414在thu没有进面试? 震惊!( ...
- jquery方法简单记录
append() - 在被选元素的结尾插入内容 prepend() - 在被选元素的开头插入内容 after() - 在被选元素之后插入内容 before() - 在被选元素之前插入内容 firs ...
- Android下so注入汇总
/** 作者:蟑螂一号* 原文链接:http://www.sanwho.com/133.html* 转载请注明出处*/ Android下so注入是基于ptrace系统调用,因此要想学会andro ...
- python基础1之python介绍、安装、变量和字符编码、数据类型、输入输出、数据运算、循环
开启python之路 内容概要: 一.python介绍 二.安装 三.第一个python程序 四.变量和字符编码 五.用户输入 六.数据类型 七.一切皆对象 八.数据运算 九.if else 流程判断 ...
- Android环境下使用call_usermodehelper()以及调试
有时候设备驱动需要做一些与其他的设备通信的操作,但是驱动本身又不可以去实作,那这个时候就可以通过调用用户态的软件,通过这个软件和其他的设备进行通信. 那在内核态如何去调用用户态的程序呢?call_us ...
- libgdx学习记录12——圆角矩形CircleRect
libgdx提供了ShapeRenderer这个工具,用它可以画点.画线.画圆.画矩形.画椭圆.画扇形,但是没有提供画圆角矩形的方法. 刚开始自己尝试分成8端,4端画直线,4端画扇形,发现多了半径几部 ...
- 程序员大佬推荐的java学习路线
作为我的第一篇博客,我第一个想到的就是在校时就看到的这篇文章.并且在之后的时间里自己都反复观看过,有时候这不单单是一篇学习路线,也是审视自己技术能力的里程碑,和激励自己的鞭挞绳. 先来个书籍清单: & ...