1890

将树的每个节点都转换为区间的形式 然后再利用线段树对结点更新 这题用了延迟标记 相对普通线段树 多了dfs的转换 把所要求的转换为某段区间

RE了N次 最后没办法了 记得有个加栈的语句 拿来加上A了。。

 #pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<vector>
#include<algorithm>
using namespace std;
#define N 50010
#define LL long long
vector<int>w[N];
LL lleft[N],rright[N],po[N],c[N],cnt;
LL o[N];
LL s[N<<],te[N<<];
void up(int w)
{
s[w] = s[w<<]+s[w<<|];
}
void build(int l,int r,int w)
{
if(l==r)
{
s[w] = c[l];
return ;
}
int m = (l+r)>>;
build(l,m,w<<);
build(m+,r,w<<|);
up(w);
}
void pushdown(int w,int d)
{
if(te[w])
{
te[w<<] += te[w];
te[w<<|]+=te[w];
s[w<<] += (d-d/)*te[w];
s[w<<|]+=d/*te[w];
te[w] = ;
}
}
void update(int a,int b,LL v,int l,int r,int w)
{
if(a<=l&&b>=r)
{
te[w] += v;
s[w] += v*(r-l+);
return ;
}
pushdown(w,r-l+);
int m = (l+r)>>;
if(a<=m)
update(a,b,v,l,m,w<<);
if(b>m)
update(a,b,v,m+,r,w<<|);
up(w);
}
LL query(int a,int b,int l,int r,int w)
{
if(a<=l&&b>=r)
{
return s[w];
}
pushdown(w,r-l+);
int m = (l+r)>>;
LL re =;
if(a<=m)
re+=query(a,b,l,m,w<<);
if(b>m)
re+=query(a,b,m+,r,w<<|);
return re;
}
void dfs(int u)
{
int i;
for(i = ; i < (int)w[u].size() ; i++)
{
int v = w[u][i];
dfs(v);
if(lleft[u]==-)
lleft[u] = lleft[v];
else
lleft[u] = min(lleft[v],lleft[u]);
if(rright[u]==-)
rright[u] = rright[v];
else
rright[u] = max(rright[u],rright[v]);
}
cnt++;
c[cnt] = o[u];
po[u] = cnt;
if(lleft[u]==-)
lleft[u] = cnt;
else
lleft[u] = min(lleft[u],cnt);
if(rright[u]==-)
rright[u] = cnt;
else
rright[u] = max(rright[u],cnt);
}
int main()
{
int n,q,s0,x,u,v,i;
char ss[];
memset(lleft,-,sizeof(lleft));
memset(rright,-,sizeof(rright));
scanf("%d%d%d",&n,&q,&s0);
o[] = s0;
for(i = ; i <= n ; i++)
w[i].clear();
for(i = ; i <= n ; i++)
{
scanf("%d%d",&u,&v);
u++;
w[u].push_back(i);
o[i] = v;
}
dfs();
build(,n,);
while(q--)
{
scanf("%s%d%d%d",ss,&x,&u,&v);
x++;
if(ss[]=='e')
{
int pp = po[x];
LL tx = query(pp,pp,,n,);
if(tx<u)
update(pp,pp,v,,n,);
}
else if(ss[]=='d')
{
int ll = lleft[x];
int rr = rright[x];
int nu = rr-ll+;
LL tx = query(ll,rr,,n,);
if(1.0*tx/nu<u)
update(ll,rr,v,,n,);
}
}
for(i = ; i <= n ; i++)
printf("%lld\n",query(po[i],po[i],,n,));
return ;
}

最新文章

  1. 【效率】专为Win7系统设计的极简番茄计时器 - MiniPomodoro (附源码)
  2. 二叉树 最近祖先lca + 两个结点的最小路径
  3. JAVABEAN连接各数据库
  4. Storyboard的使用以及使用多个Storyboard的方法
  5. HiveSQL解析过程详解 | 学步园
  6. Oracle定义两个变量,并对两个变量的值的长度进行判断
  7. Root resource classes
  8. C#中,三种强制类型转换的对比
  9. WPF实现分页控件
  10. MSMQ队列的简单使用
  11. jvm 线上命令
  12. AndroidStudio制作个人资料界面模块以及SQLite数据库的使用
  13. sudo 与输出重定向
  14. ioi2018集训队自选题:最短路练习题
  15. web.xml配置Servlet出错(DispatcherServlet)
  16. 6.form表单四种提交方式
  17. 【Android】Scroller分析
  18. Dubbo -- 系统学习 笔记 -- 示例 -- 分组聚合
  19. 深海划水队项目--七天冲刺之day7
  20. 将相关数据拼成所需JSON数据

热门文章

  1. Mongodb DB shell数据操作
  2. [Interview][CodingExam]
  3. linux命令 chattr超级权限控件
  4. linux乱码问题:LANG变量的秘诀
  5. python3 pyqt5 和eric5配置教程
  6. poj 2947 Widget Factory
  7. 内容自适应UILabel
  8. 使用Sqlserver事务发布实现数据同步
  9. storm sum aggregate 原语 聚合 本地测试
  10. 使用Compass制作雪碧图