首页 > 其他分享 >SPOJ375--Query on a tree(树链剖分)

SPOJ375--Query on a tree(树链剖分)

时间:2023-02-03 10:04:20浏览次数:46  
标签:剖分 -- tree mid son int QUERY line include

Description:

You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.

We will ask you to perfrom some instructions of the following form:

CHANGE i ti : change the cost of the i-th edge to ti
or
QUERY a b : ask for the maximum edge cost on the path from node a to node b
Input
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.

For each test case:

In the first line there is an integer N (N <= 10000),
In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 1000000),
The next lines contain instructions "CHANGE i ti" or "QUERY a b",
The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.

Output


For each "QUERY" operation, write one integer representing its result.

Example
Input:


1

3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE

Output:


1
3
在线上的区间求最值树剖模板题。

AC代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<iomanip>
#include<math.h>
using namespace std;
typedef long long ll;
typedef double ld;
const int N = 1e4 + 7;
#define ls nd<<1
#define rs nd<<1|1
int eg[N][4], pos[N], sz[N], top[N], fat[N], dep[N], son[N];
int id=0,n;
int i,j,k;
struct Edge
{
    int nxt,to;
} e[N<<1];
int head[N],tot=0;
void addeage(int u,int v)
{
    e[++tot].nxt=head[u], e[tot].to=v;
    head[u]=tot;
}

void dfs1(int u,int fa)
{
    son[u]=0;
    sz[u]=1;
    dep[u]=dep[fa]+1;
    for(i=head[u];i;i=e[i].nxt )
    {
        int v=e[i].to;
        if( v==fa )
            continue;
        fat[v]=u;
        dfs1(v, u);
        sz[u]+=sz[v];
        if( sz[v]>sz[son[u]] )
            son[u]=v;
    }
}

void dfs2(int u, int fa, int fq)
{
    pos[u]=++id;
    top[u]=fq;
    if( son[u] )
    {
        dfs2(son[u], u, fq);
    }
    for ( int i=head[u]; i; i=e[i].nxt )
    {
        int v=e[i].to;
        if( v==fa || v==son[u] )
            continue;
        dfs2(v, u, v);
    }
}
struct Node
{
    int maxv;
} tr[N<<2];
void pushup(int nd)
{
    tr[nd].maxv=max(tr[ls].maxv, tr[rs].maxv);
}
void modify(int nd,int l,int r,int p,int val)
{
    if(l==r)
    {
        tr[nd].maxv=val;
        return;
    }
    int mid=(l+r)>>1;
    if( mid>=p )
        modify(ls,l,mid,p,val);
    else
        modify(rs,mid+1,r,p,val);
    pushup(nd);
}
int query(int nd,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)
    {
        return tr[nd].maxv;
    }
    int mid=(l+r)>>1;
    int mx=0;
    if(mid>=L)
        mx=max(mx,query(ls,l,mid,L,R));
    if(mid<R)
        mx=max(mx,query(rs,mid+1,r,L,R));
    return mx;
}
void swap(int &a, int &b)
{
    a=a^b;
    b=a^b;
    a=a^b;
}
int query2(int u, int v)
{
    int f1=top[u],f2=top[v];
    int ret=0;
    while(f1!=f2)
    {
        if( dep[f1]<dep[f2] )
            swap(f1,f2);
            swap(u, v);
        ret=max(ret,query(1,1,n,pos[f1],pos[u]) );
        u=fat[f1];
        f1=top[u];
    }
    if( u==v )
        return ret;
    if( dep[u]>dep[v] )
        swap(u, v);
    ret=max(ret, query(1,1,n,pos[son[u]],pos[v]) );
    return ret;
}
void init()
{
    memset(head,0,sizeof(head));
    tot=0;
    id=0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while( T-- )
    {
        init();
        scanf("%d", &n );
        for(i=1; i<n; i++ )
        {
            int x,y,z;
            scanf("%d %d %d",&x,&y,&z);
            eg[i][1]=x;
            eg[i][2]=y;
            eg[i][3]=z;
            addeage(x,y);
            addeage(y,x);
        }
        dfs1(1,1);
        dfs2(1,1,1);
        for(i=1; i<n; i++)
        {
            if( dep[eg[i][1]]<dep[eg[i][2]] )
                swap(eg[i][1], eg[i][2]);
            modify(1,1,n,pos[eg[i][1]],eg[i][3]);
        }
        for(;;)
        {
            char ch[10];
            int x,y;
            scanf("%s",ch);
            if( ch[0]=='D' )
            {
                break;
            }
            scanf("%d %d",&x,&y);
            if( ch[0]=='Q' )
            {
                printf("%d\n",query2(x,y) );
            }
            else if(ch[0]=='C')
            {
                modify(1,1,n,pos[eg[x][1]],y);
            }
        }
    }
    return 0;
}

 

标签:剖分,--,tree,mid,son,int,QUERY,line,include
From: https://blog.51cto.com/u_15952369/6034929

相关文章

  • 栈和队列
    栈和队列都是通过动态集合来存储数据,在栈和队列中添加和删除数据都是预先设定的。在栈(Stack)中,被删除的元素是最近添加的元素,所以栈的实现方式是后进先出(Last-in,First-out......
  • Codeforces Round #596 C. p-binary
    给定N和p,让你找到满足2^x+p最少有多少不同的项。就把N转成二进制然后枚举P的个数就是答案,昨天特判没写好,今天早上起来发现被卡掉了。rank又出1000了。AC代码:#include<......
  • HDU6198 number number number(打表 矩阵快速幂)
    题意就是找到用K个斐波那契数组不成的最小的数字是谁。先打表找规律1421233348852326609可以发现递推规律:F[n]=4*(F[n-1]-F[n-2])+F[n-3]如果直接递推打......
  • Educational Codeforces Round 75 D. Salary Changing(二分)
    题意就是:给n个人发工资,总钱数为s。每个人有一个工资范围。要求一个发工资方案,使得工资中位数最大,求这个中位数。考虑到中位数最大,于是我们可以二分。但是每个人的工资......
  • 树链剖分
    “在一棵树上进行路径的修改、求极值、求和”乍一看只要线段树就能轻松解决,实际上,仅凭线段树是不能搞定它的。我们需要用到一种貌似高级的复杂算法——树链剖分。树链剖分......
  • Educational Codeforces Round 75 C Minimize The Integer
    这道题的意思就是给出一个由数字组成的字符串,相邻的数字可以互换位置,但是如果相邻的为同奇同偶这样就不能交换。让我们求交换任意次数可以产生的最小数。这条限制就是说......
  • 2019年10月23日总结
    这周已经快把数据结构的各种知识点结束了,到区域赛还有半个多月的时间,这段时间就用来总结各种知识点怎么去使用。然后刷一些数据结构的题,然后好好消化一下这些知识点,把各种......
  • codeforces 595 C2. Good Numbers (hard version)
    给出Q组查询,每组给出一个N找到一个>=n的m,m可以分解成不同的3的幂次相加。可以看题意解释,就是转化为3^0,3^1,...,3^m,每个只能出现最多一次,但是可以不同组合,输出符合条件最......
  • 2019年10月20日训练日记
    最近家里发生了一点事,这个周末没怎么看题,Treap和ST表也几乎把能看的题看了,但是这方面的题比较少,然后刷了51nod,后面的题已经有点做不动了,五级题就已经很难了,想继续再刷下去......
  • POJ3468 A Simple Problem with Integers(SplayTree做法)
    DescriptionYouhave N integers, A1, A2,..., AN.Youneedtodealwithtwokindsofoperations.Onetypeofoperationistoaddsomegivennumbertoea......