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%的数据,type≤2type≤2

对于100%100%的数据,2≤n,q≤300000,1≤w≤109,1≤type≤32≤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;
}

(微笑)

时间: 2024-11-10 00:57:45

SZOJ 167 Lca裸题的相关文章

POJ 1330 LCA裸题~

POJ 1330 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an anc

HDU 2586 How far away ?(LCA裸题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 #include<bits/stdc++.h> #define lson rt << 1, l, m #define rson rt << 1 | 1, m + 1, r using namespace std; typedef long long ll; static const ll inf = (1 << 32); static const int

POJ 2195 Going Home 最小费用流 裸题

给出一个n*m的图,其中m是人,H是房子,.是空地,满足人的个数等于房子数. 现在让每个人都选择一个房子住,每个人只能住一间,每一间只能住一个人. 每个人可以向4个方向移动,每移动一步需要1$,问所有人移动到房子里的最少花费. 其中,n,m<=100,最多有100个人. 最小给用流裸题. 建立一个超级源点,跟每一个房子连一条边,容量为1,花费为0 每一个人与超级汇点连一条边,容量为1,花费为0 一个房子与每一个人建一条边,房子指向人,容量为1,花费用2者的距离(不是直线距离) 然后跑最小费用流算

hdu1159 poj1458 LCS裸题

HDU 1159 题意:找LCS 思路:裸题 n*m的写法,我的写法好像比较奇怪...用一个ci保存s2第i位可以做为s1的公共子序列的最大值,s1的每一位遍历s2,遍历的时候记录前面出现过的ci的最大值,ci一定是一个连序的上升序列,我的好像不是正经的LCS的算法,改天还是要学习一个的 AC代码: #include "iostream" #include "string.h" #include "stack" #include "qu

HDU 4893 线段树裸题

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2512    Accepted Submission(s): 751 Problem Description Recently, Doge got a funny birthday present from his new friend, Pro

POJ 3624 Charm Bracelet(01背包裸题)

Charm Bracelet Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 38909   Accepted: 16862 Description Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fill it with the best charms possible fro

HDOJ-1232 畅通工程【并查集裸题】

题目传送门 : http://acm.hdu.edu.cn/showproblem.php?pid=1232 并查集的裸题 AC code: #include <iostream> #define MAXN 1050 using namespace std; int pre[MAXN]; int Find(int pos) { int r = pos; while (r != pre[r]) r = pre[r]; int i = pos; while (i != r) { int t = p

【不可能的任务22/200】【填坑】bzoj3224 splay裸题

人生第一道splay不出所料是一道裸题,一道水题,一道2k代码都不到的题 1 #include <cstdio> 2 int root,N=0,n,p,q; 3 int fa[100001],c[100001][2],size[100001],sp[100001]; 4 void rot(int x) 5 { 6 int y=fa[x],k=(c[y][0]==x); 7 size[y]=size[c[y][k]]+size[c[x][k]]+1;size[x]=size[c[x][!k]]+

HDU 1102 最小生成树裸题,kruskal,prim

1.HDU  1102  Constructing Roads    最小生成树 2.总结: 题意:修路,裸题 (1)kruskal //kruskal #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b using na