就是给自己留个底子,免得忘记
如果忘了(画个向量图,rate为当前节点到父亲节点的各种权值)!!!
1.求和
int f(int x)
{
if(x==pre[x]) return x;
int fx=pre[x];
pre[x]=f(pre[x]);
sum[x]+=sum[fx];
return pre[x];
}
int fx=f(x),fy=f(y);
if(fx==fy&&sum[y]-sum[x]!=val)
{
ans++; continue;
}
else if(fx!=fy)
{
pre[fy]=fx;
sum[fy]=sum[x]+val-sum[y];
}
2.奇偶
int f(int x)
{
if(x==pre[x]) return x;
int t=f(pre[x]);
sum[x]=(sum[x]+sum[pre[x]])%2;
return pre[x]=t;
}
int v(int x,int y,int z)
{
int fx=f(x),fy=f(y);
if(fx==fy)
{
if((sum[x]+sum[y]+z)%2) return 0;
return 1;
}
pre[fy]=fx;
sum[fy]=(sum[x]-sum[y]+z+4)%2 ;
return 1;
}
3.相对距离
int f(int x)
{
if(x==pre[x]) return pre[x];
int fx=pre[x];
pre[x]=f(pre[x]);
xsum[x]+=xsum[fx]; ysum[x]+=ysum[fx];
return pre[x];
}
int lx=edge[now].x,ly=edge[now].y;
int flx=f(lx), fly=f(ly);
pre[fly]=flx;
xsum[fly]=xsum[lx]-xsum[ly]-edge[now].dx;
ysum[fly]=ysum[lx]-ysum[ly]-edge[now].dy;
int qx=q[i].x,qy=q[i].y;
if(f(qx)!=f(qy))
{
ans[q[i].pos]=-1;
}
else
{
ans[q[i].pos]=abs(xsum[qx]-xsum[qy])+abs(ysum[qx]-ysum[qy]);
}
4.种类
int f(int x)
{
if(x==pre[x]) return pre[x];
int fx=pre[x];
pre[x]=f(pre[x]);
sum[x]=(sum[x]+sum[fx])%2;
return pre[x];
}
for(int i=1;i<=q;++i)
{
int x,y; char s[10];
scanf("%d%d%s",&x,&y,s);
int temp;
if(s[0]=='n') temp = 1; else temp = 0;
int fx=f(x) , fy=f(y);
if(fy!=fx)
{
pre[fy]=fx;
sum[fy]=(sum[x]-temp-sum[y]+4)%2;
}
}
0与父亲节点同种,1与父亲节点不同种。
5.权值(题目奇葩要求)
int f(int x)
{
if(x!=pre[x]) pre[x]=f(pre[x]);
return pre[x];
}
void v(int x,int y)
{
int fx=f(x),fy=f(y);
if(fx!=fy)
{
if(rate[fx]>rate[fy])
{
pre[fy]=fx;
}
else if(rate[fx]<rate[fy]) pre[fx]=fy;
else
{
if(fx>fy) pre[fx]=fy;
else pre[fy]=fx;
}
}
}