FZU2176(二维线段树+dfs)
传送门:easy problem
题意:给定一棵n个节点以1为根的树,初始每个节点的值为0,现在我们要在树上进行一些操作,操作有两种类型。
1 x val 表示对以x为根的子树的每个点进行加权操作(我们定义每个节点的深度为每个节点到根1的距离),如果 y是以x为根的子树中的点那么 y节点的权值增加 ((dep[y]-dep[x])%k+1)*val 其中dep[y]表示y节点的深度,k为一个常数(1<=k<=5)
2 x 查询当前x节点的权值。
分析:这题用树链剖分有点大材小用,直接一个dfs将每点遍历完又回到该点重新标号映射到线段树上,然后每修改该点及它的子节点时在线段树上操作。由题意可发现,每隔k个深度权值增加是一样的,而k又很小,因此用k棵线段树分别维护整段区间内深度模k的点余x(0<x<k)的点,然后修改区间时分别给区间内模k为0,1...k-1的点修改,也就是给k棵线段树进行区间修改。
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 100000000
#define inf 0x3f3f3f3f
#define eps 1e-6
#define N 50010
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define PII pair<int,int>
using namespace std;
struct edge
{
int v,next;
edge(){}
edge(int v,int next):v(v),next(next){}
}e[N];
int head[N],vis[N],tot;
int col[][N<<],num;
int st[N],ed[N],dep[N];
int n,m,k;
void init()
{
FILL(head,-);
FILL(vis,);
tot=;
}
void addedge(int u,int v)
{
e[tot]=edge(v,head[u]);
head[u]=tot++;
}
void dfs(int u,int fa)
{
st[u]=++num;
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v;
dep[v]=dep[u]+;
dfs(v,u);
}
ed[u]=num;
}
void build(int l,int r,int rt)
{
for(int i=;i<k;i++)col[i][rt]=;
if(l==r)return;
int m=(l+r)>>;
build(lson);
build(rson);
}
void Pushdown(int rt)
{
for(int i=;i<k;i++)
if(col[i][rt])
{
col[i][rt<<]+=col[i][rt];
col[i][rt<<|]+=col[i][rt];
col[i][rt]=;
}
}
void update(int L,int R,int s,int c,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
col[s][rt]+=c;
return;
}
Pushdown(rt);
int m=(l+r)>>;
if(L<=m)update(L,R,s,c,lson);
if(m<R)update(L,R,s,c,rson);
}
int query(int pos,int s,int l,int r,int rt)
{
if(l==r)
{
return col[s][rt];
}
Pushdown(rt);
int m=(l+r)>>;
if(pos<=m)return query(pos,s,lson);
else return query(pos,s,rson);
}
int main()
{ int t,a,b,op,cas=;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
init();
for(int i=;i<n;i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
}
num=;dep[]=;
dfs(,-);
build(,num,);
printf("Case#%d:\n",cas++);
while(m--)
{
scanf("%d",&op);
if(op==)
{
scanf("%d",&a);
printf("%d\n",query(st[a],(dep[a]+)%k,,num,));
}
else
{
scanf("%d%d",&a,&b);
for(int i=;i<k;i++)
{
int s=((dep[a]+)%k+i)%k;
update(st[a],ed[a],s,b*(i+),,num,);
}
}
}
}
}
FZU2176(二维线段树+dfs)的更多相关文章
- UVA 11297 线段树套线段树(二维线段树)
题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要 不同的处理方式,非叶子形成的 ...
- POJ2155 Matrix二维线段树经典题
题目链接 二维树状数组 #include<iostream> #include<math.h> #include<algorithm> #include<st ...
- HDU 1823 Luck and Love(二维线段树)
之前只知道这个东西的大概概念,没具体去写,最近呵呵,今补上. 二维线段树 -- 点更段查 #include <cstdio> #include <cstring> #inclu ...
- poj 2155:Matrix(二维线段树,矩阵取反,好题)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17880 Accepted: 6709 Descripti ...
- poj 1195:Mobile phones(二维线段树,矩阵求和)
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14391 Accepted: 6685 De ...
- POJ 2155 Matrix (二维线段树)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17226 Accepted: 6461 Descripti ...
- HDU 4819 Mosaic (二维线段树)
Mosaic Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total S ...
- HDU 4819 Mosaic --二维线段树(树套树)
题意: 给一个矩阵,每次查询一个子矩阵内的最大最小值,然后更新子矩阵中心点为(Max+Min)/2. 解法: 由于是矩阵,且要求区间最大最小和更新单点,很容易想到二维的线段树,可是因为之前没写过二维的 ...
- HDU 4819 Mosaic(13年长春现场 二维线段树)
HDU 4819 Mosaic 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意:给定一个n*n的矩阵,每次给定一个子矩阵区域(x,y,l) ...
随机推荐
- 解决外网与内网或内网之间的通信,NAT穿透
在网络编码中会发现程序在局域网中是可以适用的,但是在外网与内网之间和内网与内网之间就不可行.问题就在于NAT.首先介绍下NAT. NAT的作用NAT(Network Address Translato ...
- [Java 并发] Java并发编程实践 思维导图 - 第二章 线程安全性
依据<Java并发编程实践>一书整理的思维导图.
- 我是小白之<%%>用法
下面知识都是摘录自网络 <%= %>输出,等价于Response.Write()<%%> 写代码<%-- --%>注释. <% %>跟其它serv ...
- (摘录)MSMQ的简单介绍
MSMQ(MicroSoft Message Queue,微软消息队列)是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任 ...
- sqlserver05 字符串拆分
-- 规则:将 gs-abc-aa-aa 拆分为一下字符 -- gs-abc-aa-aa -- gs-abc-aa -- gs-abc -- gs select * from dbo.f_split( ...
- ubuntu 13.10 Rhythmbox不能播放mp3 和中文乱码的问题
1.ubuntu 13.10 Rhythmbox不能播放mp3的解决方法 软件中心搜索(ubuntu额外的版权受限软件)不带括号 2.中文乱码问题解决方法: 终端顺序操作 : 1. sudo ged ...
- spring mvc controller间跳转 重定向
1. 需求背景 需求:spring MVC框架controller间跳转,需重定向.有几种情况:不带参数跳转,带参数拼接url形式跳转,带参数不拼接参数跳转,页面也能显示. 本来以为挺简单的一 ...
- C中程序的内存分配
一.预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. ...
- 一句话解释JVM中空间分配担保的问题
先解释YGC: 当对象生成在EDEN区失败时,出发一次YGC,先扫描EDEN区中的存活对象,进入S0区,S0放不下的进入OLD区,再扫描S1区,若存活次数超过阀值则进入OLD区,其它进入S0区,然后S ...
- Photoshop图象切片保存为网页HTML(DIV+CSS布局)的方法
首先,制作图象切片(以一张图片为例子) 一.选择“切片”工具,在图像上拖动以分割图像(例如:一张图像切割2次就形成3个切片)切片后如下图 二.设置切片选项(如大小.目标链接.图片说明等等):选择“切片 ...