SZOJ 167 Lca裸题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SZOJ 167 Lca裸题相关的知识,希望对你有一定的参考价值。

一道.......一道我改了一周的裸题

无根树建双向边

无根树建双向边

无根树建双向边

重要的事情说三遍(微笑)

还有要开longlong

还有双向边不是双倍边(微笑)

 

我真是,能把自己气吐血10次就不把自己气吐血9次

 

【问题描述】

已知一棵nn个点的树,点从1开始标号,树上每条边都有一个正整数边权。

qq个询问,每个询问由type,u,vtype,u,v三个正整数构成。

type=1type=1时,询问uu到vv路径上所有边权的二进制异或和。

type=2type=2时,询问uu到vv路径上所有边权之和。

type=3type=3时,询问uu到vv路径上边权的最大值。

【输入格式】

第一行两个正整数n,qn,q,表示节点个数与询问数。

接下来nn-11行,每行三个正整数u,v,wu,v,w,表示编号为uu的节点与编号为vv的节点之间有一条权值为ww的边,保证给定的是一棵树。

接下来qq行,每行三个正整数type,u,vtype,u,v,表示一个询问。

【输出格式】

对每个询问输出一行表示答案。

【样例输入】
4 4
1 2 1
2 3 3
2 4 4
1 1 3
1 3 4
2 1 4
3 1 3
【样例输出】
2
7
5
3
【数据规模】

对于40%40%的数据,type=1type=1

对于80%80%的数据,type2type≤2

对于100%100%的数据,2n,q300000,1w109,1type32≤n,q≤300000,1≤w≤109,1≤type≤3。

对于至少25%25%的数据,树是随机生成的,这些数据会在所有测试点中比较均匀地分布。 

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<cstring>
using namespace std;
stack<int> s;
int g[600001],dep[600001],n,cnt,T,q,sum2[600001];
long long sum1[600001];
int f[600001][21],g1[600001][21];
int root1;
struct node{
    int nxt,to,w,fr;
}e[600001];
inline void addedge(int x,int y,int z){
    e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;e[cnt].w=z;e[cnt].fr=x;
}
inline void dfs(int u){
    dep[u]=1;s.push(u);
    while(!s.empty()){
        u=s.top();s.pop();
       for(int i=1;i<=19;i++)
               f[u][i]=f[f[u][i-1]][i-1];
        for(int i=1;i<=19;i++)
            g1[u][i]=max(g1[u][i],max(g1[f[u][i-1]][i-1],g1[u][i-1]));
        for(int i=g[u];i;i=e[i].nxt){
            if(!dep[e[i].to]){
                dep[e[i].to]=dep[u]+1;
                f[e[i].to][0]=u;
                g1[e[i].to][0]=e[i].w;
                s.push(e[i].to);
            }
        }
    }
}
inline int swim(int x,int h){
    for(int i=0;h;i++,h>>=1)
        if(h&1) x=f[x][i];
    return x;
}
inline int swim1(int x,int h){
    int maxnum=-100007;
    for(int i=0;h;i++,h>>=1)
        if(h&1){
            maxnum=max(maxnum,g1[x][i]);
            x=f[x][i];
//            printf("g1=%d maxnum=%d\n",g1[x][i],maxnum);
        }
//    printf("mmmax==%d\n",maxnum);
    return maxnum;
}
inline int Lca(int x,int y){
    if(dep[x]<dep[y]){
        int t;
        t=x;
        x=y;
        y=t;
    }
    x=swim(x,dep[x]-dep[y]);
    if(x==y) return x;
    for(int i=19;~i;i--){if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];}
    return f[x][0];
}
inline int Lca1(int x,int y){
    if(dep[x]<dep[y]){
        int t;
        t=x;
        x=y;
        y=t;
    }
    int maxnum=swim1(x,dep[x]-dep[y]);
//    printf("swim1 maxnum=%d %d %d\n",maxnum,x,dep[x]-dep[y]);
    x=swim(x,dep[x]-dep[y]);
    if(x==y) return maxnum;
    for(int i=19;~i;i--){
        if(f[x][i]!=f[y][i]){
            maxnum=max(maxnum,max(g1[x][i],g1[y][i]));
            x=f[x][i],y=f[y][i];
        }
    }
    maxnum=max(maxnum,max(g1[x][0],g1[y][0]));
    return maxnum;
}
inline void dfs1(int u){
    s.push(u);
    while(!s.empty()){
        u=s.top();s.pop();
        for(int i=g[u];i;i=e[i].nxt){
            if(e[i].to==f[u][0])continue;
            s.push(e[i].to);
            sum1[e[i].to]=sum1[u]+e[i].w;
            sum2[e[i].to]=sum2[u]^e[i].w;
        }
    }
}
inline void Jimmy(){
    scanf("%d%d",&n,&q);
    for(int i=1,u,v,w;i<=n-1;i++){
        scanf("%d%d%d",&u,&v,&w);
        addedge(u,v,w);addedge(v,u,w);
    }

    //f[1][0]=1;
    dfs(1);
    //for(int i=1;i<=n;i++)cout<<f[i][0]<<",";
    dfs1(1);
    //cout<<sum2[5]<<","<<sum2[1]<<endl;
   for(int i=1,u1,v1,ty;i<=q;i++){
        scanf("%d%d%d",&ty,&u1,&v1);
        if(ty==1) printf("%d\n",sum2[u1]^sum2[v1]);
        if(ty==2) printf("%lld\n",sum1[u1]+sum1[v1]-2*sum1[Lca(u1,v1)]);
        if(ty==3) printf("%d\n",Lca1(u1,v1));
    }
//    printf("FFFFFFFFF    %d %d\n",g1[3][0],g1[3][1]);
    return;
}
int main(){
        Jimmy();
    return 0;
}

(微笑)

以上是关于SZOJ 167 Lca裸题的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ-1602: [Usaco2008 Oct]牧场行走 (LCA炒鸡大裸题)

HDU 2586 How far away ? << LCA转RMQ+ST表 求树上任两点最短距离裸题

SZOJ 150 生命众筹

szoj461四校联考0430挑战

BZOJ-4281Zwi?zek Harcerstwa Bajtockiego 树上倍增LCA

BZOJ 3732 Network Kruskal重构树+倍增LCA