【题目描述】
已知一个数列,我会告诉你某两项的差,然后你要回答我的问题
【输入格式】
第一行是两个数 n,m,表示数列有n项,一共有m条指令。
接下来有m行,每行一个指令,指令分两类:
1. I_i_j_k 表示第i比第j项大k.
2. A_i_j 询问当前第i项与第j项差的绝对值.('_'表示空格)
【输出格式】
对于每个2类指令,输出一行,无法判断时输出-1
我们考虑用并查集来维护,我们维护他与根节点的相对大小
对于加法操作,我们先找到他们各自的根节点,如果不同,就对y点的祖先打上标记,因为我们要使x的查询值比y大z,则应在y的祖先处打上的标记值为
对于询问操作,若不在并查集则输出-1,否则输出相对大小的绝对值差即可
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<ctime>
using namespace std;
int n,m,f[10005],fr[10005];
char op[1];
int find(int x)
{
if(x==f[x]) return x;
int fx=find(f[x]);
fr[x]+=fr[f[x]];
f[x]=fx;
return fx;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) f[i]=i,fr[i]=0;
for(int i=1;i<=m;i++)
{
scanf("%s",op);
if(op[0]=='I')
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
int fx=find(x),fy=find(y);
if(fx!=fy)
{
f[fy]=fx;
fr[fy]=fr[x]-fr[y]-z;
}
}
else
{
int x,y;
scanf("%d%d",&x,&y);
int fx=find(x),fy=find(y);
if(fx!=fy) printf("-1\n");
else printf("%d\n",abs(fr[x]-fr[y]));
}
}
}