题目意思很明白:

给你一棵有n个节点的树,对树有下列操作:

I c1 c2 k 意思是把从c1节点到c2节点路径上的点权值加上k

D c1 c2 k 意思是把从c1节点到c2节点路径上的点权值减去k

Q a 查询节点a的权值

数据大小 节点个数 n[1,50000], 操作次数 op[0,30000];

不会树链剖分 故只有想其他的方法。

这道题有点类似今年上海网络赛的1003 ,不过那题我没做;

算法思路:

以节点1 为根,求出节点i 的 dfs序列 tim[i][2];

其中tim[i][0]存的是进入节点i的时间 ,tim[i][1]存的是离开节点i的时间

看操作: I a b k, 节点a到b的路径上所有点+k;最朴素的算法首先找到他们的最近公共祖先(LCA)(我用RMQ)写的;然后在路径上的每一个节点都+k;

假设树根是1

从a到树根的每一个节点x都满足tim[x][0]<=tim[a][0]<=tim[x][1];如此 如果引入一个数列nt,如果nt(tim[a][0])+=k,那么 nt数列从tim[x][0]到tim[x][1]项的和就加了k,这就相当于把从a到根节点的每一个节点的权值加上了k;

如果节点x不在a到根的路径上呢?那么只有可能是tim[x][0]>tim[a][0] or tim[x][1]<tim[a][0]  故上面的这种做法对其他的点没有影响

根据这种思路 ,那解法就相对简单了:

加上差分数列的思想

a b的LCA是t,把 a b节点都加上k,然后把t的父节点-2;当然 t节点是加了两遍的 所以需要减去一遍 也就是把t节点-1,父节点当然也要+1了

如果有了dfs序,就可以很清晰的看出来 如果一个节点x在这条路径上 那么tim[x][0]<=one of (tim[a][0],tim[b][0])<=tim[x][1];

附上代码渣渣:

 // hdu 3966
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <string>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<stdlib.h>
#include <vector>
using namespace std; #define ll __int64
#define CL(a,b) memset(a,b,sizeof(a))
#define MAX_NODE 50010 int n,m,q; int log_2(int x)
{
return (int)(log((double)x)/log(2.0));
} int tim[MAX_NODE][],ti;
int rmq[MAX_NODE*][],cq,fv[MAX_NODE];
int pre[MAX_NODE];
int value[]; typedef struct myedge
{
int v,next;
}E; E edge[];
int head[],ce; void inithead()
{
CL(head,-);
ce=;
}
void addedge(int s,int e)
{
edge[ce].v=e;edge[ce].next=head[s];head[s]=ce++;
edge[ce].v=s;edge[ce].next=head[e];head[e]=ce++;
} void initrmq()
{
int i,j;
for(j=;(<<j)<=cq;j++)
{
for(i=;i+(<<j)-<=cq;i++)
{
rmq[i][j]=min(rmq[i][j-],rmq[i+(<<(j-))][j-]);
}
}
}
int quermq(int s,int e)
{
int i=log_2(e-s+);
return min(rmq[s][i],rmq[e-(<<i)+][i]);
} ll nt[]; int lowbit(int i)
{
return i&(-i);
} void modify(int i,ll v)
{
if(i==)return ;
for(i;i<=n;i+=lowbit(i))
{
nt[i]+=v;
}
} ll sum(int i)
{
ll rem=;
for(i;i>;i-=lowbit(i))
rem+=nt[i];
return rem;
} int dfs(int i,int pr)
{
ti++;
tim[i][]=ti;
// cout<<i<<" tim "<<ti<<endl;
rmq[++cq][]=tim[i][];
fv[i]=cq;
pre[ti]=pr;
int p=head[i];
while(p!=-)
{
int v=edge[p].v;
if(tim[v][]==)
{
dfs(v,tim[i][]);
rmq[++cq][]=tim[i][];
}
p=edge[p].next;
}
tim[i][]=ti;
return ;
} void inc(int s,int e,int k)
{
int rs=fv[s];
int re=fv[e];
int rt=quermq(min(rs,re),max(rs,re));
re=tim[e][];
rs=tim[s][];
// cout<<rs<<' '<<re<<' '<<rt<<' '<<pre[rt]<<endl;
if(s==e)
{
value[s]+=k;
return ;
}
modify(rs,k);
modify(re,k);
modify(rt,-k);
modify(pre[rt],-k);
} void dec(int s,int e,int k)
{
k=-k;
int rs=fv[s];
int re=fv[e];
int rt=quermq(min(rs,re),max(rs,re));
re=tim[e][];
rs=tim[s][];
if(s==e)
{
value[s]+=k;
return ;
}
modify(rs,k);
modify(re,k);
modify(rt,-k);
modify(pre[rt],-k);
} ll que(int k)
{
int rl=tim[k][];
int rr=tim[k][];
// cout<<rl<<' '<<rr<<endl;
return (ll)value[k]+sum(rr)-sum(rl-);
} char op[]; int main()
{
while(scanf("%d %d %d",&n,&m,&q)!=EOF)
{
CL(nt,);
CL(rmq,);cq=;
CL(fv,);
CL(pre,);
CL(tim,);ti=;
inithead();
int i,j,k;
int a,b,c;
for(i=;i<=n;i++)
{
scanf("%d",value+i);
}
for(i=;i<n;i++)
{
scanf("%d %d",&a,&b);
addedge(a,b);
}
dfs(,);
/*
for(i=1;i<=cq;i++)
{
printf("%d ",rmq[i][0]);
}cout<<endl;
*/
initrmq();
for(i=;i<q;i++)
{
scanf("%s",op);
if(op[]=='I')
{
scanf("%d %d %d",&a,&b,&c);
inc(a,b,c);
}
else if(op[]=='D')
{
scanf("%d %d %d",&a,&b,&c);
dec(a,b,c);
}
else if(op[]=='Q')
{
scanf("%d",&a);
printf("%I64d\n",que(a));
}
} } return ;
}

HDU 3966 dfs序+LCA+树状数组的更多相关文章

  1. BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) , ...

  2. HDU 6203 ping ping ping(dfs序+LCA+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意: n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连 ...

  3. POJ 2763 Housewife Wind(DFS序+LCA+树状数组)

    Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 11419   Accepted: 3140 D ...

  4. BZOJ 2819: Nim dfs序维护树状数组,倍增

    1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...

  5. 【BZOJ1103】大都市meg(DFS序,树状数组)

    题意:有一颗树,1号点为根,保证编号小的点深度较小,初始状态每条边都没有被标记,要求实现两个操作在线: A:将连接x,y的边标记 W:查询从1到x的路径上有多少条边未被标记 n<=2*10^5 ...

  6. 2018.06.30 BZOJ4765: 普通计算姬(dfs序+分块+树状数组)

    4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Description "奋战三星期,造台计算机".小G响应号召,花了三小时 ...

  7. BZOJ 1103: [POI2007]大都市meg(dfs序,树状数组)

    本来还想链剖的,结果才发现能直接树状数组的= = 记录遍历到达点与退出点的时间,然后一开始每个到达时间+1,退出时间-1,置为公路就-1,+1,询问直接点1到该点到达时间求和就行了- - CODE: ...

  8. 【Tyvj2133&BZOJ1146】网络管理Network(树套树,DFS序,树状数组,主席树,树上差分)

    题意:有一棵N个点的树,每个点有一个点权a[i],要求在线实现以下操作: 1:将X号点的点权修改为Y 2:查询X到Y的路径上第K大的点权 n,q<=80000 a[i]<=10^8 思路: ...

  9. 【POJ3321】Apple Tree(DFS序,树状数组)

    题意:给一棵n个节点的树,每个节点开始有一个苹果,m次操作 1.将某个结点的苹果数异或 1 2.查询一棵子树内的苹果数 n,m<=100000   思路:最近一段时间在思考树上统计问题的算法 发 ...

随机推荐

  1. 获取aplicationContext对象,从而获取任何注入的对象

    在Servlet中 方法一: 从ServletContext 取出 Spring容器上下文 ApplicationContext applicationContext = (ApplicationCo ...

  2. 解决表格里面使用text-overflow后依旧不能隐藏超出的文本

    解决表格里面使用text-overflow后依旧不能隐藏超出的文本 来源: http://blog.csdn.net/colinmuxi/article/details/9069595  (非原创,自 ...

  3. web标准(复习)--1

    XHTML CSS基础知识 一.xhtml css基础知识首先说一下我们这节课的知识点 1.文档类型 2.语言编码 3.html标签 4.css样式 5.css优先级 6.css盒模型组成 1)文档类 ...

  4. 转载:struts2和spring的结合原理(精品)

    转载网址:http://blog.sina.com.cn/s/blog_683278bc0101236z.html Ioc将所有的对象之间的关系转移到了xml配置文件中来. 在TopLogic中声明存 ...

  5. [linux]磁盘挂载

    最近磁盘空间不足了, 所以需要将更多的磁盘空间加进来. 因为目前占空间最多的就是home, 无论是下载还是本地用户的东西都是放在这里的. 将分区格式化为ext4, 然后使用blkid /dev/sda ...

  6. fiddler使用之坑

    今天一上午都在搞fiddler,之前可以抓到浏览器的请求,今天突然不行了,弄得我花一上午时间去设置浏览器代理的事情,遇到各种各样的问题,现将解决办法记录如下: 1.原来fiddler安装在E盘中,安装 ...

  7. IOS流媒体播放

    IOS流媒体播放   1. 这里的流媒体地址是指服务端那边已经调好格式的可以在ios上播放的视频流. 下面提供几个视频流的地址: NSString *linkStr = http://61.160.2 ...

  8. 使用GCD的dispatch_once创建单例

    使用GCD的dispatch_once创建单例 介绍了创建单例的方式,不过后来发现其实在ios 4.0后有更加简单的方式. 就是使用GCD的功能 代码如下: + (instantClass *)sha ...

  9. append与remove的简单使用

    点击Add More按钮页面会自动添加一个输入框和Remove按钮,点击Remove按钮则此行元素将被移除. <!DOCTYPE html> <html lang="en& ...

  10. 关于Windows高DPI的一些简单总结(Window上一般默认是96 dpi 作为100% 的缩放比率)

    我们知道,关于高DPI的支持, Windows XP时代就开始有了, 那时关于高DPI的支持比较简单, 但是从Vista/Win7 到现在Win8 /Win8.1, Windows关于高DPI的支持已 ...