51nod1199 Money out of Thin Air
链剖即可。其实就是利用了链剖后子树都在一段连续的区间内所以可以做到O(logn)查询和修改。
线段树细节打错了。。要专心!肉眼差错都能找出一堆出来显然是不行的!。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
#define qwq(x) for(edge *o=head[x];o;o=o->next)
#define lson l,mid,x<<1
#define rson mid+1,r,x<<1|1
#define ll long long
int read(){
int x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x;
}
const int nmax=5e4+5;
const int inf=0x7f7f7f7f;
struct edge{
int to;edge *next;
};
edge es[nmax<<1],*pt=es,*head[nmax];
void add(int u,int v){
pt->to=v;pt->next=head[u];head[u]=pt++;
pt->to=u;pt->next=head[v];head[v]=pt++;
}
int size[nmax],son[nmax],idx[nmax],id[nmax],w[nmax],n,m;
ll sm[nmax<<2],col[nmax<<2];
void dfs(int x,int fa){
size[x]=1;
qwq(x) if(o->to!=fa){
dfs(o->to,x);size[x]+=size[o->to];
if(!son[x]||size[o->to]>size[son[x]]) son[x]=o->to;
}
}
void DFS(int x){
id[++id[0]]=x;idx[x]=id[0];
if(son[x]) DFS(son[x]);
qwq(x) if(!idx[o->to]) DFS(o->to);
}
void build(int l,int r,int x){
col[x]=-1;
if(l==r) {
sm[x]=w[id[l]];return ;
}
int mid=(l+r)>>1;build(lson);build(rson);sm[x]=sm[x<<1]+sm[x<<1|1];
}
void pushdown(int x,int cnt){
if(col[x]!=-1){
if(col[x<<1]!=-1) col[x<<1]+=col[x];else col[x<<1]=col[x];
if(col[x<<1|1]!=-1) col[x<<1|1]+=col[x];else col[x<<1|1]=col[x];
sm[x<<1]+=col[x]*(cnt-(cnt>>1));sm[x<<1|1]+=col[x]*(cnt>>1);
col[x]=-1;
}
}
void update(int p,int add,int l,int r,int x){
if(l==r) {
sm[x]+=add;return ;
}
pushdown(x,r-l+1);
int mid=(l+r)>>1;
p<=mid?update(p,add,lson):update(p,add,rson);
sm[x]=sm[x<<1]+sm[x<<1|1];
}
void Update(int tl,int tr,int add,int l,int r,int x){
if(tl<=l&&tr>=r) {
if(col[x]!=-1) col[x]+=add;else col[x]=add;
sm[x]+=(ll)add*(r-l+1);return ;
}
pushdown(x,r-l+1);
int mid=(l+r)>>1;
if(tl<=mid) Update(tl,tr,add,lson);
if(tr>mid) Update(tl,tr,add,rson);
sm[x]=sm[x<<1]+sm[x<<1|1];
}
ll query(int tl,int tr,int l,int r,int x){
if(tl<=l&&tr>=r) return sm[x];
pushdown(x,r-l+1);
int mid=(l+r)>>1;ll ans=0;
if(tl<=mid) ans+=query(tl,tr,lson);
if(tr>mid) ans+=query(tl,tr,rson);
return ans;
}
void UPDATE(int u,int v,int d){
ll sm=query(idx[u],idx[u]+size[u]-1,1,n,1);
if(sm>=(ll)v*size[u]) return ;
Update(idx[u],idx[u]+size[u]-1,d,1,n,1);
}
void print(int l,int r,int x){
printf("%d %d %d\n",l,r,sm[x]);
if(l==r) return ;
int mid=(l+r)>>1;
print(lson);print(rson);
}
ll get(int p,int l,int r,int x){
if(l==r) return sm[x];
pushdown(x,r-l+1);
int mid=(l+r)>>1;
return p<=mid?get(p,lson):get(p,rson);
}
char s[5];
int main(){
n=read(),m=read();int u,v,d;
rep(i,2,n) u=read()+1,w[i]=read(),add(u,i);
dfs(1,0);DFS(1);build(1,n,1);
//printf("->_->\n");print(1,n,1);
rep(i,1,m){
scanf("%s",s);u=read()+1,v=read(),d=read();
if(s[0]=='S') {
if(get(idx[u],1,n,1)<v) update(idx[u],d,1,n,1);
}
else UPDATE(u,v,d);
//printf("->_->\n");print(1,n,1);
}
rep(i,1,n) printf("%lld\n",get(idx[i],1,n,1));
return 0;
}
第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行:每行表示一个操作,N 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
51nod1199 Money out of Thin Air的更多相关文章
- 51nod1199:Money out of Thin Air(线段树)
按dfs序一个一个加入线段树,可以让任何一颗子树的节点在线段树中连续,于是就可以用线段树维护整棵树了 和树剖的思想是一样的,大概一眼就看出来了,但是写了两个半天(躺 总结:记住以后写完数据结构或者数字 ...
- ural1890 Money out of Thin Air
Money out of Thin Air Time limit: 1.0 secondMemory limit: 64 MB Each employee of the company Oceanic ...
- 51Nod 1199 Money out of Thin Air (树链剖分+线段树)
1199 Money out of Thin Air 题目来源: Ural 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 一棵有N个节点的树,每 ...
- URAL 1890 . Money out of Thin Air (dfs序hash + 线段树)
题目链接: URAL 1890 . Money out of Thin Air 题目描述: 给出一个公司里面上司和下级的附属关系,还有每一个人的工资,然后有两种询问: 1:employee x y z ...
- 1890. Money out of Thin Air(线段树 dfs转换区间)
1890 将树的每个节点都转换为区间的形式 然后再利用线段树对结点更新 这题用了延迟标记 相对普通线段树 多了dfs的转换 把所要求的转换为某段区间 RE了N次 最后没办法了 记得有个加栈的语句 拿来 ...
- 51nod 1199 Money out of Thin Air(线段树+树剖分)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1199 题意: 思路:因为是一棵树,所以需要把它剖分一下再映射到线段树上, ...
- JMM(java内存模型)
What is a memory model, anyway? In multiprocessorsystems, processors generally have one or more laye ...
- 比特币_Bitcoin 简介
2008-11 Satoshi Nakamoto Bitcoin: A Peer-to-Peer Electronic Cash System http://p2pbucks.com/?p=99 ...
- Java内存模型深度解析:顺序一致性--转
原文地址:http://www.codeceo.com/article/java-memory-3.html 数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据 ...
随机推荐
- doctype声明、浏览器的标准、怪异等模式
doctype 标准(严格)模式(Standards Mode).怪异(混杂)模式(Quirks Mode),如何触发,区分他们有何意义? 触发标准模式 1.加DOCTYPE声明,比如:<!DO ...
- javascript实现数据结构与算法系列:队列 -- 链队列和循环队列实现及示例
1 队列的基本概念 队列(Queue):也是运算受限的线性表.是一种先进先出(First In First Out ,简称FIFO)的线性表.只允许在表的一端进行插入,而在另一端进行删除. 队首(fr ...
- super用法
Person类: public class Person { String _name; int _age; public Person(String name,int age) { _name= n ...
- 单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板
一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的 ...
- 【QT】找茬外挂制作
找茬外挂制作 找茬游戏大家肯定都很熟悉吧,两张类似的图片,找里面的不同.在下眼神不大好,经常瞪图片半天也找不到区别.于是乎决定做个辅助工具来解放一下自己的双眼. 一.使用工具 Qt:主要是用来做界面的 ...
- JavaWeb-Eclipse的下载和安装
Eclipse下载地址:http://www.eclipse.org/downloads/ Eclipse集成JDK 遇见弹框: 1.这是由于缺少JRE所导致的,Eclipse中带有自己的编译器,因此 ...
- Android的Testing和Instrumentation
Android提供了一系列强大的测试工具,它针对Android的环境,扩展了业内标准的JUnit测试框架.尽管你可以使用JUnit测试Android工程,但Android工具允许你为应用程序的各个方面 ...
- sql连接字符串的方法
----乌龟代码---合并列值 --********************************************************************************** ...
- border-radius几种写法的原理剖析
border-radius:40px; border-radius:40px/20px; border-radius:40px 20px; border-radius:40px 20px 10px 5 ...
- 【转】SIP 中的Dialog,call,session 和 transaction
如果你对Sip协议中Call, Dialog, Transaction和Message之间的关系感觉到迷惑,那么,那么我可以告诉你,你并不孤单,因为大多数初学者对于这些名词之间的关系都会感到疑惑. ...