树链剖分 [HDU 5044] Tree

Tree

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 2038    Accepted Submission(s): 391

Problem Description

You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are numbered from 1 to N
There are N - 1 edges numbered from 1 to N - 1.
Each node has a value and each edge has a value. The initial value is 0.
There are two kind of operation as follows:
● ADD1 u v k: for nodes on the path from u to v, the value of these nodes increase by k.
● ADD2 u v k: for edges on the path from u to v, the value of these edges increase by k.
After finished M operation on the tree, please output the value of each node and edge.

Input

The first line of the input is T (1 ≤ T ≤ 20), which stands for the number of test cases you need to solve.
The first line of each case contains two integers N ,M (1 ≤ N, M ≤105),denoting the number of nodes and operations, respectively.
The next N - 1 lines, each lines contains two integers u, v(1 ≤ u, v ≤ N ), denote there is an edge between u,v and its initial value is 0.
For the next M line, contain instructions “ADD1 u v k” or “ADD2 u v k”. (1 ≤ u, v ≤ N, -105 ≤ k ≤ 105)

Output

For each test case, print a line “Case #t:”(without quotes, t means the index of the test case) at the beginning.
The second line contains N integer which means the value of each node.
The third line contains N - 1 integer which means the value of each edge according to the input order.

Sample Input

2
4 2
1 2
2 3
2 4
ADD1 1 4 1
ADD2 3 4 2
4 2
1 2
2 3
1 4
ADD1 1 4 5
ADD2 3 2 4

Sample Output

Case #1:
1 1 0 1
0 2 2
Case #2:
5 0 0 5
0 4 0

Source

2014 ACM/ICPC Asia Regional Shanghai Online

不行、好像有点晕、= = 见代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cmath>
#include <map>
#include <iterator>
#include <cstring>
#include <string>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000") //手动加栈、windows系统容易爆栈
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define INF 0x7fffffff
#define ll long long
#define N 100002

struct Edge2
{
    int a,b;
}s[N<<1];

struct Edge
{
    int to,next;
}edge[N<<1];
int head[N],tot;

int size[N];
int deep[N];
int top[N];
int fa[N];
int son[N];
int p[N];
int fp[N];
int pos;

int n,m;
int col[N<<2][2];                                //点权为0,边权为1

template <class T>
inline bool input(T &ret)
{
    char c;int sgn;
    if(c=getchar(),c==EOF) return 0;
    while(c!=‘-‘&&(c<‘0‘||c>‘9‘)) c=getchar();
    sgn=(c==‘-‘)?-1:1;
    ret=(c==‘-‘)?0:(c-‘0‘);
    while(c=getchar(),c>=‘0‘&&c<=‘9‘) ret=ret*10+(c-‘0‘);
    ret*=sgn;
    return 1;
}

inline void out(int x)
{
    if(x>9) out(x/10);
    putchar(x%10+‘0‘);
}

inline void init()
{
    tot=0;
    pos=1;
    memset(col,0,sizeof(col));
    memset(head,-1,sizeof(head));
    memset(son,-1,sizeof(son));
}

inline void addEdge(int x,int y)
{
    edge[tot].to=y;
    edge[tot].next=head[x];
    head[x]=tot++;
}

inline void dfs1(int now,int pre,int d)
{
    deep[now]=d;
    fa[now]=pre;
    size[now]=1;
    for(int i=head[now];i!=-1;i=edge[i].next)
    {
        int next=edge[i].to;
        if(next!=pre)
        {
            dfs1(next,now,d+1);
            size[now]+=size[next];
            if(son[now]==-1 || size[next]>size[son[now]])
            {
                son[now]=next;
            }
        }
    }
}

inline void dfs2(int now,int tp)
{
    top[now]=tp;
    p[now]=pos++;
    fp[p[now]]=now;
    if(son[now]==-1) return;
    dfs2(son[now],tp);
    for(int i=head[now];i!=-1;i=edge[i].next)
    {
        int next=edge[i].to;
        if(next!=son[now] && next!=fa[now])
        {
            dfs2(next,next);
        }
    }
}

inline void change_node(int x,int y,int z)
{
    int f1=top[x];
    int f2=top[y];
    while(f1!=f2)
    {
        if(deep[f1]<deep[f2])
        {
            swap(x,y);
            swap(f1,f2);
        }
        col[p[f1]][0]+=z;
        col[p[x]+1][0]-=z;
        x=fa[f1];
        f1=top[x];
    }
    if(deep[x]>deep[y]) swap(x,y);
    col[p[x]][0]+=z;
    col[p[y]+1][0]-=z;
}

inline void change_edge(int x,int y,int z)
{
    int f1=top[x];
    int f2=top[y];
    while(f1!=f2)
    {
        if(deep[f1]<deep[f2])
        {
            swap(x,y);
            swap(f1,f2);
        }
        col[p[f1]][1]+=z;
        col[p[x]+1][1]-=z;
        x=fa[f1];
        f1=top[x];
    }
    if(x==y) return;
    if(deep[x]>deep[y]) swap(x,y);
    col[p[x]+1][1]+=z;
    col[p[y]+1][1]-=z;
}

inline int convert(int pos)
{
    int a=s[pos].a;
    int b=s[pos].b;
    if(deep[a]>deep[b]) return a;
    return b;
}

int main()
{
    int T,iCase=1;
    input(T);
    while(T--)
    {
        init();
        input(n);
        input(m);
        for(int i=1;i<n;i++)
        {
            input(s[i].a);
            input(s[i].b);
            addEdge(s[i].a,s[i].b);
            addEdge(s[i].b,s[i].a);
        }
        dfs1(1,0,0);
        dfs2(1,1);
        while(m--)
        {
            char op[10];
            int a,b,c;
            scanf("%s",op);
            input(a);input(b);input(c);
            if(op[3]==‘1‘) change_node(a,b,c);
            else change_edge(a,b,c);
        }
        for(int i=1;i<=n;i++)
        {
            col[i][0]+=col[i-1][0];
            col[i][1]+=col[i-1][1];
        }

        printf("Case #%d:\n",iCase++);
        for(int i=1;i<=n;i++)
        {
            if(i>1) putchar(‘ ‘);
            out(col[p[i]][0]);
        }
        printf("\n");
        if(n>1) out(col[p[convert(1)]][1]);
        for(int i=2;i<n;i++)
        {
            putchar(‘ ‘);
            out(col[p[convert(i)]][1]);
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-10-11 20:44:47

树链剖分 [HDU 5044] Tree的相关文章

树链剖分 [HDU 3966] Aragorn&#39;s Story

Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3544    Accepted Submission(s): 995 Problem Description Our protagonist is the handsome human prince Aragorn comes from The Lord

树链剖分 [POJ 3237] Tree

Tree Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instruc

树链剖分 [HDU 5029] Relief grain

Relief grain Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submission(s): 1254    Accepted Submission(s): 299 Problem Description The soil is cracking up because of the drought and the rabbit kingdom is

HDU 5044 Tree(树链剖分)

HDU 5044 Tree 题目链接 就简单的树链剖分,不过坑要加输入外挂,还要手动扩栈 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 100005; #pragma comment(linker, "/STACK:1024000000,1024000000"

HDU 5044 Tree 树链剖分

一棵树,初始边权和点权都为0 现在有m个操作,每一个操作: ADD1 u v k: for nodes on the path from u to v, the value of these nodes increase by k. ADD2 u v k: for edges on the path from u to v, the value of these edges increase by k. 操作完后,输出每一个点的点权和每一条边的边权(边权按照输入顺序输出) 我们把边权也当做点权处

HDU 5044 (树链剖分+树状数组+点/边改查)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5044 题目大意:修改链上点,修改链上的边.查询所有点,查询所有边. 解题思路: 2014上海网赛的变态树链剖分模板题.将以往树链剖分的点&边修改和查询合在一起之后,难度上去不少. 第一个卡人点是读入优化. 第二个卡人点是树状数组.由于要查询所有点,如果使用线段树,每次都要扫到底层才能取出点值,必T无疑. 然后使用树状数组之后,树链剖分的点/边修改写法有些变动. 点查询变化不大. 边查询只要查询一下

HDU 4718 The LCIS on the Tree(树链剖分)

Problem Description For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i <= j <= N and Si < Si+1 < Si+2 < ... < Sj-1 < Sj , then the sequence Si, Si+1, ... , Sj is a CIS(Continuous Increasing Subsequence). The

hdu 4912 Paths on the tree(树链剖分+贪心)

题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道,要求尽量选出多的通道,并且两两通道不想交. 解题思路:用树链剖分求LCA,然后根据通道两端节点的LCA深度排序,从深度最大优先选,判断两个节点均没被标 记即为可选通道.每次选完通道,将该通道LCA以下点全部标记. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include

(中等) HDU 5293 Tree chain problem,树链剖分+树形DP。

Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There are m chain on the tree, Each chain has a certain weight. Coco would like to pick out some chains any two of which do not share common vertices.Find out the