Lyp

来源:互联网 发布:什么是网络安全意识 编辑:程序博客网 时间:2024/05/29 14:43

众所周知,我们的 lyp 神犇外号叫Altman,的确,在另一个平行宇宙,lyp神犇就是一个——Altman。
有一天,lyp神犇遇到了另一个平行宇宙中的他,得知了在其他的宇宙中,Altman是存在的,那么,怪兽也是存在的咯。
作为一个有名的oier,lyp神犇想要统计一下各个宇宙中怪兽的战斗力,他发现,一些怪兽在不同的宇宙都出现过(!. !,难不成怪兽不穿越,算了,不管了),每一个Altman都提供给lyp一些信息,告诉他一个怪兽比另一个怪兽的战斗力大多少(这个数可以是负数)。
Altman神犇为了给你以表现机会,将这些信息都给你,并会时不时地问你两个怪兽之间谁更强。
假设Altman们提到了怪兽都按1~n编号。
Altman们的信息的格式是 X A B C
其中 x 固定为1AB 是两个 1~n 的整数,表示怪兽编号, A 怪兽的战斗力比 B 怪兽的战斗力大 CC 为整数),保证信息之间不矛盾。
Lyp的询问的格式是: Y A B
Y 固定为 2A,B 是怪兽编号,属于 1~n , 如果 AB 强,输出 A ;如果 BA 强,输出 B ,如果无法判断或怪兽们一样强,输出 0


输入描述 Input Description

1 行,两个数nqn 表示怪兽总数,q 表示询问与信息的总数;
2~q+1 行, 每一行是一个信息或询问,格式如题;


输出描述 Output Description

对于每一个询问,用单独一行回答。


输入样例 Sample Input

3 3
1 1 2 3
1 3 2 1
2 1 3


输出描述 Sample Output

1


数据范围 Data Size

30%:n100,q300
100%:n30000,q50000,|c|5000


分析 I Think

特殊的路径压缩,设 Fi 表示 i 的父亲节点, fi 表示 X 次操作前 i 的父亲节点, gi 表示 X 次操作前 ifi 大多少,其中 X 是一个不确定的数字。则 Fi=ff...fi
当我们需要连边 (a,b,c)时 ( abc ),,先更新 fa,ga,fb,gb ,至其现在的父亲节点。然后合并 a,b 的父亲节点, 其中 fafbgb+cga


代码 Code

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 30300;int father[Size];int f[Size];int g[Size];int n,m;void read(int &);int find(int);void uni(int,int,int);void updata(int);int main(){    read(n);    read(m);    for(int i=1;i<=n;++i)        father[i] = i;    int type,x,y,a;    while( m-- ){        read(type);        if(type == 1){            read(x);            read(y);            read(a);            uni(x,y,a);        }        else{            read(x);            read(y);            updata(x);            updata(y);            if(find(x)!=find(y) || f[x]==f[y])                printf("0\n");            else if(f[x] > f[y])                printf("%d\n",x);            else                printf("%d\n",y);        }    }    return 0;}void read(int &_in){    _in = 0;    int flag = 1;    char ch = getchar();    while(ch!='-' && (ch>'9'||ch<'0'))        ch = getchar();    if(ch == '-'){        flag = -1;        ch = getchar();    }    while(ch<='9' && ch>='0'){        _in = _in*10+ch-'0';        ch = getchar();    }    _in *= flag;}int find(int x){    if(x != father[x])        father[x] = find(father[x]);    return father[x];}void uni(int x,int y,int c){    int p = find(x);    int q = find(y);    updata(x);    updata(y);    f[p] = c+f[y]-f[x];    father[p] = g[p] = q;}void updata(int x){    while(g[g[x]]){        f[x] += f[g[x]];        g[x] = g[g[x]];    }}
0 0