【DFS序】【线段树】bzoj4034 [HAOI2015]T2
分开维护树的入栈序和出栈序,用两棵线段树。回答时就是用一颗的减去另一棵的。
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
#define N 100001
ll sumv[2][N<<2],delta[2][N<<2];
void pushdown(int o,int rt,int sz)
{
if(delta[o][rt])
{
delta[o][rt<<1]+=delta[o][rt];
delta[o][rt<<1|1]+=delta[o][rt];
sumv[o][rt<<1]+=delta[o][rt]*(ll)(sz-(sz>>1));
sumv[o][rt<<1|1]+=delta[o][rt]*(ll)(sz>>1);
delta[o][rt]=0;
}
}
void Update(int o,int ql,int qr,int v,int rt,int l,int r)
{
if(ql<=l&&r<=qr)
{
delta[o][rt]+=(ll)v;
sumv[o][rt]+=(ll)v*(ll)(r-l+1);
return;
}
int m=(l+r>>1);
pushdown(o,rt,r-l+1);
if(ql<=m) Update(o,ql,qr,v,rt<<1,l,m);
if(m<qr) Update(o,ql,qr,v,rt<<1|1,m+1,r);
sumv[o][rt]=sumv[o][rt<<1]+sumv[o][rt<<1|1];
}
ll Query(int o,int qr,int rt,int l,int r)
{
if(r<=qr) return sumv[o][rt];
int m=(l+r>>1); ll res=0;
pushdown(o,rt,r-l+1);
res+=Query(o,qr,rt<<1,l,m);
if(m<qr) res+=Query(o,qr,rt<<1|1,m+1,r);
return res;
}
int n,m,a[N];
int e,v[N<<1],first[N],next[N<<1];
void AddEdge(int U,int V)
{
v[++e]=V;
next[e]=first[U];
first[U]=e;
}
int Ls[N],Rs[N],oLs[N],oRs[N],xu[N<<1];
int tot,to2,to3;
void dfs(int U,int Fa)
{
Ls[U]=++tot;
xu[++to3]=U;
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa)
dfs(v[i],U);
Rs[U]=tot;
xu[++to3]=U;
oRs[U]=oLs[U]=++to2;
}
void df2(int U,int Fa)
{
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa)
{
df2(v[i],U);
oLs[U]=min(oLs[U],oLs[v[i]]);
}
}
bool hav[N];
int Map[N];
int main()
{
int x,y,op;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<n;++i)
{
scanf("%d%d",&x,&y);
AddEdge(x,y);
AddEdge(y,x);
}
dfs(1,0);
df2(1,0);
int last=0;
for(int i=1;i<=to3;++i)
if(!hav[xu[i]])
{
Map[xu[i]]=last;
hav[xu[i]]=1;
}
else
last=xu[i];
for(int i=1;i<=n;++i)
{
Update(0,Ls[i],Ls[i],a[i],1,1,n);
Update(1,oRs[i],oRs[i],a[i],1,1,n);
}
for(;m;--m)
{
scanf("%d%d",&op,&x);
if(op==1)
{
scanf("%d",&y);
Update(0,Ls[x],Ls[x],y,1,1,n);
Update(1,oRs[x],oRs[x],y,1,1,n);
}
else if(op==2)
{
scanf("%d",&y);
Update(0,Ls[x],Rs[x],y,1,1,n);
Update(1,oLs[x],oRs[x],y,1,1,n);
}
else
printf("%I64d\n",Query(0,Ls[x],1,1,n)-((!Map[x])?0:Query(1,oRs[Map[x]],1,1,n)));
}
return 0;
}
【DFS序】【线段树】bzoj4034 [HAOI2015]T2的更多相关文章
- 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...
- [luoguP3178] [HAOI2015]树上操作(dfs序 + 线段树 || 树链剖分)
传送门 树链剖分固然可以搞. 但还有另一种做法,可以看出,增加一个节点的权值会对以它为根的整棵子树都有影响,相当于给整棵子树增加一个值. 而给以某一节点 x 为根的子树增加一个权值也会影响当前子树,节 ...
- Codeforces Round #442 (Div. 2)A,B,C,D,E(STL,dp,贪心,bfs,dfs序+线段树)
A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...
- CodeForces 877E Danil and a Part-time Job(dfs序+线段树)
Danil decided to earn some money, so he had found a part-time job. The interview have went well, so ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
- POJ 3321 DFS序+线段树
单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4: 5: #include < ...
- 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树
题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...
随机推荐
- git使用笔记(九)操作原理
By francis_hao Nov 27,2016 参考[1]的一张图已经把git的基本原理描述的很清楚了,如下: 下面以实例演示其过程,需要用到两个命令cat-file和ls-fil ...
- Linux下rsync 安装与配置
1.什么是rsync Rsync(remote synchronize)是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.Rsync使用所谓的“Rsync算法”来使本地和远 程两个 ...
- webpack 小记
零.入口与输出 //对像语法 entry: { aa: __dirname + '/src/aa.js', //(chunkName :path) bb: __dirname + '/src/b ...
- NGINX: 限制连接的实践 (Defense DDOS)
参考: [ nginx防止DDOS攻击配置 ] 关于限制用户连接,Nginx 提供的模块: [ ngx_http_limit_req_module ] [ ngx_http_limit_conn_mo ...
- Linux eject弹出光驱
Linux eject命令用于退出抽取式设备. 若设备已挂入,则eject会先将该设备卸除再退出. 语法 eject [-dfhnqrstv][-a <开关>][-c <光驱编号&g ...
- linux驱动基础系列--Linux I2c驱动分析
前言 主要是想对Linux I2c驱动框架有一个整体的把控,因此会忽略协议上的某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型.sysfs等也不进行详细说明原理,涉及到i2c协议部分也只 ...
- linux驱动基础系列--linux spi驱动框架分析(续)
前言 这篇文章是对linux驱动基础系列--linux spi驱动框架分析的补充,主要是添加了最新的linux内核里设备树相关内容. spi设备树相关信息 如之前的文章里所述,控制器的device和s ...
- time_t转化成日期格式小工具
time_t转化成日期格式小工具下载 http://files.cnblogs.com/files/lansan0701/TimeTool.zip
- js 触发LinkButton点击事件,执行后台方法
页面 <asp:LinkButton ID="lbtButton" runat="server" CssClass="lbtButton&qu ...
- JSP 基础之 JSTL <c:choose>用法 if else
<c:choose> <c:when test="${condition1}"> condition1为true </c:when> <c ...