ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SP375 QTREE - Query on a tree

2019-10-05 09:52:34  阅读:207  来源: 互联网

标签:int ll tree tp son QTREE dfs2 Query top


SP375 QTREE - Query on a tree

我是借这道题来说说如何从c++改到c的

1.我怕麻烦,所以把结构体拆了(忍痛割爱我封装的线段树)

2.max、swap函数进行了手写

max:

ll llmax(ll x,ll y){return x>y?x:y;}

swap:

x^=y^=x^=y

emm...这的确是一个神奇的swap,不用函数

至于为什么是对的用人类智慧法即可

c++代码:(线段树封装)

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
typedef long long ll;
struct line{
    int from,to;
    ll val;
    int conec;
}s[N];
int n;
int hed[N],tal[N<<1],nxt[N<<1],cnt=0;
ll val[N<<1];
int fa[N];
int dep[N];
int size[N]={0};
int son[N]={0};
int dfn[N];
int rk[N];
int indexy=0;
int top[N];
ll v[N];
ll llmax(ll x,ll y){return x>y?x:y;}
struct Sugment_Tree{
    ll t[N<<2];
    #define mid (l+r)/2
    void push_up(int num){
        t[num]=llmax(t[num<<1],t[num<<1|1]);
    }
    void build(int l,int r,int num){
        if(l==r){
            t[num]=v[l];
            return;
        }
        build(l,mid,num<<1),build(mid+1,r,num<<1|1);
        push_up(num);
    }
    void upd(int l,int r,int num,int pos,ll SUM){
        if(l>pos||r<pos) return;
        if(l==r&&r==pos){
            t[num]=SUM;
            return;
        }
        upd(l,mid,num<<1,pos,SUM);
        upd(mid+1,r,num<<1|1,pos,SUM);
        push_up(num);
    } 
    ll ask(int l,int r,int num,int L,int R){
        if(l>R||r<L) return 0;
        if(l>=L&&r<=R) return t[num];
        return llmax(ask(l,mid,num<<1,L,R),ask(mid+1,r,num<<1|1,L,R));
    }
}T;
void addege(int x,int y,ll z){
    cnt++;
    tal[cnt]=y;
    val[cnt]=z;
    nxt[cnt]=hed[x];
    hed[x]=cnt;
}
void dfs1(int u,int pa){
    fa[u]=pa;
    size[u]=1;
    for(int i=hed[u];i;i=nxt[i]){
        int v=tal[i];
        if(v==fa[u]) continue;
        dep[v]=dep[u]+1;
        dfs1(v,u);
        size[u]+=size[v];
        if(size[v]>size[son[u]]) son[u]=v;
    }
}
void dfs2(int u,int tp){
    indexy++;
    dfn[u]=indexy;
    rk[dfn[u]]=u;
    top[u]=tp;
    if(!son[u]) return;
    dfs2(son[u],tp);
    for(int i=hed[u];i;i=nxt[i]){
        int v=tal[i];
        if(v==fa[u]||v==son[u]) continue;
        dfs2(v,v);
    }
}

ll cgn(int x,int y){
    ll ans=0;
    //LCA不能算进来!!!!!! 
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans=llmax(ans,T.ask(1,n,1,dfn[top[x]],dfn[x]));
        x=fa[top[x]];
    }
    if(dep[x]<dep[y]) swap(x,y);
    ans=llmax(ans,T.ask(1,n,1,dfn[y]+1,dfn[x]));
    return ans;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d%d%lld",&s[i].from,&s[i].to,&s[i].val);    
        addege(s[i].from,s[i].to,s[i].val);
        addege(s[i].to,s[i].from,s[i].val);
    }
    dep[1]=1;
    dfs1(1,1);
    dfs2(1,1);
    for(int i=1;i<n;i++){
        if(fa[s[i].from]==s[i].to) v[dfn[s[i].from]]=s[i].val,s[i].conec=dfn[s[i].from];
        else v[dfn[s[i].to]]=s[i].val,s[i].conec=dfn[s[i].to];
    } 
    /*
    for(int i=1;i<=n;i++)
        cout<<v[i]<<" ";
    cout<<endl;
    */
    T.build(1,n,1);
    char c[10];
    while(1){
        scanf("%s",c);
        if(c[0]=='D') break;
        else if(c[0]=='Q'){
            int x,y;
            scanf("%d%d",&x,&y);
            if(x==y){
                printf("0\n");
                continue;
            }
            printf("%lld\n",cgn(x,y));
        }
        else{
            int pos;
            ll va;
            scanf("%d%lld",&pos,&va);
            T.upd(1,n,1,s[pos].conec,va);
        }
    }
    return 0;
} 

c:

#include <ctype.h>
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#define N 100005
typedef long long ll;
int from_P[N];
int to_P[N];
ll val_P[N];
int conec_P[N];
int n;
int hed[N],tal[N<<1],nxt[N<<1],cnt=0;
ll val[N<<1];
int fa[N];
int dep[N];
int size[N]={0};
int son[N]={0};
int dfn[N];
int rk[N];
int indexy=0;
int top[N];
ll v[N];
int TE;
ll llmax(ll x,ll y){return x>y?x:y;}
    ll t[N<<2];
    #define mid (l+r)/2
    void push_up(int num)
    {
        t[num]=llmax(t[num<<1],t[num<<1|1]);
    }
    void build(int l,int r,int num)
    {
        if(l==r)
        {
            t[num]=v[l];
            return;
        }
        build(l,mid,num<<1),build(mid+1,r,num<<1|1);
        push_up(num);
    }
    void upd(int l,int r,int num,int pos,ll SUM)
    {
        if(l>pos||r<pos) return;
        if(l==r&&r==pos)
        {
            t[num]=SUM;
            return;
        }
        upd(l,mid,num<<1,pos,SUM);
        upd(mid+1,r,num<<1|1,pos,SUM);
        push_up(num);
    } 
    ll ask(int l,int r,int num,int L,int R)
    {
        if(l>R||r<L) return 0;
        if(l>=L&&r<=R) return t[num];
        return llmax(ask(l,mid,num<<1,L,R),ask(mid+1,r,num<<1|1,L,R));
    }
void addege(int x,int y,ll z)
{
    cnt++;
    tal[cnt]=y;
    val[cnt]=z;
    nxt[cnt]=hed[x];
    hed[x]=cnt;
}
void dfs1(int u,int pa)
{
    fa[u]=pa;
    size[u]=1;
    for(int i=hed[u];i;i=nxt[i])
    {
        int v=tal[i];
        if(v==fa[u]) continue;
        dep[v]=dep[u]+1;
        dfs1(v,u);
        size[u]+=size[v];
        if(size[v]>size[son[u]]) son[u]=v;
    }
}
void dfs2(int u,int tp)
{
    indexy++;
    dfn[u]=indexy;
    rk[dfn[u]]=u;
    top[u]=tp;
    if(!son[u]) return;
    dfs2(son[u],tp);
    for(int i=hed[u];i;i=nxt[i])
    {
        int v=tal[i];
        if(v==fa[u]||v==son[u]) continue;
        dfs2(v,v);
    }
}

ll cgn(int x,int y)
{
    ll ans=0;
    //LCA不能算进来!!!!!! 
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) x^=y^=x^=y;
        ans=llmax(ans,ask(1,n,1,dfn[top[x]],dfn[x]));
        x=fa[top[x]];
    }
    if(dep[x]<dep[y]) x^=y^=x^=y;
    ans=llmax(ans,ask(1,n,1,dfn[y]+1,dfn[x]));
    return ans;
}
int main()
{
    scanf("%d",&TE);
    while(TE--)
    {
        cnt=0;
        indexy=0;
        for(int i=0;i<N;i++) hed[i]=0;
        for(int i=0;i<N;i++) dep[i]=0;
        for(int i=0;i<N;i++) size[i]=0;
        for(int i=0;i<N;i++) son[i]=0;
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%lld",&from_P[i],&to_P[i],&val_P[i]);    
            addege(from_P[i],to_P[i],val_P[i]);
            addege(to_P[i],from_P[i],val_P[i]);
        }
        dep[1]=1;
        dfs1(1,1);
        dfs2(1,1);
        for(int i=1;i<n;i++)
        {
            if(fa[from_P[i]]==to_P[i]) v[dfn[from_P[i]]]=val_P[i],conec_P[i]=dfn[from_P[i]];
            else v[dfn[to_P[i]]]=val_P[i],conec_P[i]=dfn[to_P[i]];
        } 
        /*
        for(int i=1;i<=n;i++)
            cout<<v[i]<<" ";
        cout<<endl;
        */
        build(1,n,1);
        char c[10];
        while(1)
        {
            scanf("%s",c);
            if(c[0]=='D') break;
            else if(c[0]=='Q')
            {
                int x,y;
                scanf("%d%d",&x,&y);
                if(x==y)
                {
                    printf("0\n");
                    continue;
                }
                printf("%lld\n",cgn(x,y));
            }
            else
            {
                int pos;
                ll va;
                scanf("%d%lld",&pos,&va);
                upd(1,n,1,conec_P[pos],va);
            }
        }
    }
    return 0;
} 

 

标签:int,ll,tree,tp,son,QTREE,dfs2,Query,top
来源: https://www.cnblogs.com/QYJ060604/p/11623986.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有