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) ...
随机推荐
- SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
问题的原因是无法找到org.slf4j.impl.StaticLoggerBinder,我找了一下,确实没有该类,网上搜了一下下面是官方的解答http://www.slf4j.org/codes.ht ...
- 使用C语言实现字符串中子字符串的替换
描述:编写一个字符串替换函数,如函数名为 StrReplace(char* strSrc, char* strFind, char* strReplace),strSrc为原字符串,strFind是待 ...
- jQuery Validation让验证变得如此easy(一)
一.官网下载jquery,和jquery validation plugin http://jqueryvalidation.org/ 二.引入文件 <script src="js/j ...
- Android面试题收集(有具体答案)
Android面试题目及其答案 1.Android dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念 DVM指dalivk的虚拟机.每个Android应用程序都在它自己的进程中执行,都 ...
- C#、ASP.NET、WinForm - 实现邮件发送的功能
转载自:http://www.cnblogs.com/mingmingruyuedlut/archive/2011/10/14/2212255.html 发送邮件所用的核心知识点 微软封装好的Mail ...
- form里两个submit按钮,在onsubmit中判断哪个被点
记下别人的解决方法(有效): 方法1:(已验证过) <form name="form1" onsubmit="show()"> ..... < ...
- Spring boot jar 后台运行
start(){ now=`date "+%Y%m%d%H%M%S"` exec java -Xms256m -Xmx512m -jar /alidata/server/webap ...
- 1.1.0-学习Opencv与MFC混合编程之---全屏截图,保存为BMP图像(并增加快捷键)
源代码:http://download.csdn.net/detail/nuptboyzhb/3961677 Ø 添加全屏截图菜单项,菜单项的属性如下; Ø 为该菜单项建立类向导. 编辑消息处理函 ...
- Spring mvc interceptor配置拦截器,没有登录跳到登录页
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- /etc/security/limits.conf 设置
jrhdpt01:/root# cat /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535 * soft npro ...