hdu5692【dfs序】【线段树】
Snacks
Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 4446    Accepted Submission(s): 980
由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化。小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次。另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机。
为小度熊规划一个路线,使得路线上的价值总和最大。
对于每组数据,包含两个整数n,m(1≤n,m≤100000),表示有n个零食机,m次操作。
接下来n−1行,每行两个整数x和y(0≤x,y<n),表示编号为x的零食机与编号为y的零食机相连。
接下来一行由n个数组成,表示从编号为0到编号为n−1的零食机的初始价值v(|v|<100000)。
接下来m行,有两种操作:0 x y,表示编号为x的零食机的价值变为y;1 x,表示询问从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。
本题可能栈溢出,辛苦同学们提交语言选择c++,并在代码的第一行加上:
`#pragma comment(linker, "/STACK:1024000000,1024000000") `
对于每次询问,输出从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。
6 5
0 1
1 2
0 3
3 4
5 3
7 -5 100 20 -5 -7
1 1
1 3
0 2 -1
1 1
1 5
102
27
2
20
这是一条已经看懂的分割线
基本就是按照题解写的思路
先dfs遍历所有的路径 确定dfs序 这个序就是未来线段树的的基础
相当于线段树的先序遍历
用这些节点建立线段树 转换成了求区间最大值
RE 了一发是因为cnt忘记初始化了
WA了一发是因为inf定的0x3f3f3f3f太小了 改成1e18就过了
类型改成longlong的时候inf也要记得改过来
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define inf 1e18
using namespace std;
const int maxn = 100005;
int n, t, m;
struct node{
    int v, next;
}edges[maxn << 2];
int head[maxn], tot, cnt;//tot为边的数量 cnt用于标记dfs序
int in[maxn] ,out[maxn];
long long lazy[maxn << 2];
long long dis[maxn], b[maxn];
long long sum[maxn << 2], cost[maxn];
void init()
{
    memset(head, -1, sizeof(head));
    tot = cnt = 0;
}
void addedge(int u, int v, int &k)
{
    edges[k].v = v;
    edges[k].next = head[u];
    head[u] = k++;
}
void pushup(int idx)
{
    sum[idx] = max(sum[idx<<1], sum[idx<<1|1]);
}
void pushdown(int idx)
{
    if(lazy[idx]){
        sum[idx<<1] += lazy[idx];
        sum[idx<<1|1] += lazy[idx];
        lazy[idx<<1] += lazy[idx];
        lazy[idx<<1|1] += lazy[idx];
        lazy[idx] = 0;
    }
    return;
}
void build(int l, int r, int root)
{
    lazy[root] = 0;
    if(l == r){
        sum[root] = b[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, root << 1);
    build(mid + 1, r, root << 1 | 1);
    pushup(root);
}
void update(int l, int r, int ll, int rr, int idx, int val)
{
    //让l和r进入llrr的区间内
    if(l >= ll && r <= rr){
        sum[idx] = sum[idx] + val;//val为变化量
        lazy[idx] = lazy[idx] + val;
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(idx);
    if(mid >= ll) update(l, mid, ll, rr, idx << 1, val);
    if(mid < rr) update(mid + 1, r, ll, rr, idx << 1 | 1, val);
    pushup(idx);
}
long long mm = -1;
void query(int l, int r, int ll, int rr, int idx)
{
    if(l >= ll && r <= rr){
        mm = max(mm, sum[idx]);
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(idx);
    if(mid >= ll) query(l, mid, ll, rr, idx << 1);
    if(mid < rr) query(mid + 1, r, ll, rr, idx << 1 | 1);
}
void dfs(int u, int pre)
{
    //cnt标记dfs序
    in[u] = ++cnt;
    b[cnt] = dis[u];
    for(int k = head[u]; k != -1; k = edges[k].next){
        int v = edges[k].v;
        if(v == pre) continue;
        dis[v] = dis[u] + cost[v];
        dfs(v, u);
    }
    out[u] = cnt;
}
int main()
{
    cin>>t;
    for(int cas = 1; cas <= t; cas++){
        init();
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n - 1; i++){
            int u, v;
            scanf("%d%d", &u, &v);
            addedge(u, v, tot);
            addedge(v, u, tot);
        }
        for(int i = 0; i < n; i++){
            scanf("%lld", &cost[i]);
        }
        dis[0] = cost[0];
        dfs(0, -1);//dfs路径 dfs序
        build(1, n, 1);
        printf("Case #%d:\n", cas);
        while(m--){
            int op, x, y;
            scanf("%d", &op);
            if(op == 1){
                scanf("%d", &x);
                mm = -inf;
                query(1, n, in[x], out[x], 1);
                printf("%lld\n", mm);
            }
            else{
                scanf("%d%d", &x, &y);
                long long change = (long long)y - cost[x];
                update(1, n, in[x], out[x], 1, change);
                cost[x] = y;
            }
        }
    }
    return 0;
}
hdu5692【dfs序】【线段树】的更多相关文章
- hdu5692   dfs序线段树
		这是补的知识点,按先序遍历的顺序建立dfs序,用左右两个值代表整个区间,因为dfs序最重要的特点就是子树的区间是连续的 建立线段树时,需要用重新标过的 下标来建立 #pragma comment(li ... 
- HDU5692(dfs序+线段树)
		Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ... 
- 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\), ... 
- F - Change FZU - 2277 (DFS序+线段树)
		题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ... 
- BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
		题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ... 
随机推荐
- Java 代码块:静态代码块、构造代码块、构造函数块
			Class : StaticFa package edu.bai.du.lime.staticCode; public class StaticFa { // 随着类的声明而执行 static { S ... 
- WinInet  API详解
			一.概述 WinInet(「Windows Internet」)API帮助程序员使用三个常见的Internet协议,这三个协议是:用于World Wide Web万维网的超文本传输协议(HTTP:Hy ... 
- PostgreSQL存储过程(5)-异常错误处理
			1. 异常错误处理 在PL/pgSQL函数中,如果没有异常捕获,函数会在发生错误时直接退出,与其相关的事物也会随之回滚.我们可以通过使用带有EXCEPTION子句的BEGIN块来捕获异常并使其从中恢复 ... 
- MVC的初步认识理论
			说起来写博客可以说一个月没来啦,我们狠狠的放假一个月,想一想都奇怪.而是想一下以后的假期还会这样吗?或许这是作为学生的我们的最后一个长的假期啦,以后就要面对工作再也没有寒假暑假之分啦,在这一个月的时间 ... 
- iOS - 截屏,view截图的基本方法
			推荐一个第三方好用的框架:SDScreenshotCapture #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice cur ... 
- iOS 触摸事件与手势识别器(Gesture Recognizers)
			Gesture Recognizers与触摸事件分发 通过一个问题引出今天的知识: 1.大家应该都遇见过 当需要给tableView 添加一个tap 手势识别 但是tableView 的上的事件(滑动 ... 
- 【面试题】Java EE面试题
			第一部分:Servlet/JSP快速入门 1. 请列举至少6种javaEE技术,并简述其作用. 解析: javaEE是一系列的技术,主要包扩13种.对于开发人员来说,了解几种主要的技术是非常 ... 
- c++ malloc与free
			今天看STL内存配置器的时候,第一级配置器就是直接用malloc.free来管理内存. 而free和malloc都只需要传入或传出一个指针就能分配和释放内存了. 编译器是如何知道,这个指针指向的空间的 ... 
- QT开发之旅四邮件发送工具
			终于有了一个晚上安静的写写程序,最近一直忙着公司商务上的事情,一直想用QT实现一个调用最底层socket通信来实现的邮件发送程序,以前用C#写过,微软都封装好的,不知道底层是如何实现的,只知道调用方法 ... 
- 【大数据系列】win10不借助Cygwin安装hadoop2.8
			一.下载安装包 解压安装包并创建data,name,tmp文件夹 二.修改配置文件 1.core-site.xml <?xml version="1.0" encoding= ... 
