第一次交TLE,说好的并查集昂。
好吧我改。求和、个数 在各个步骤独立算。。
还是TLE。
看来是方法太慢,就一个数组(fa),移动的话,移动跟结点要遍历一次 T T
嗯,那就多一个数组。
0.189S。
#include<cstdio>
const int MAXN=100000+10;
int fa[MAXN],num[MAXN],idx[MAXN],cnt,n,m;
long long sum[MAXN];
int find(const int & x) //查找父结点,顺带路径压缩
{
return fa[x]==x? x: fa[x]=find(fa[x]);
}
inline void init()
{
for(int i=1;i<=n;i++)
{
fa[i]=idx[i]=sum[i]=i;
num[i]=1;
}
cnt=n;
}
inline void Union()
{
int p,q;
scanf("%d%d",&p,&q);
int rootp=find(idx[p]); //找p的根节点
int rootq=find(idx[q]);
if(rootp!=rootq)
{
fa[rootp]=rootq;
sum[rootq]+=sum[rootp];
num[rootq]+=num[rootp];
}
}
inline void update(const int &p,const int &rootp)
{
sum[rootp]-=p;
num[rootp]--;
idx[p]=++cnt;
sum[idx[p]]=p;
num[idx[p]]=1;
fa[idx[p]]=idx[p];
}
inline void move()
{
int p,q;
scanf("%d%d",&p,&q);
int rootp=find(idx[p]); //找p的根节点
int rootq=find(idx[q]);
if(rootp!=rootq)
{
update(p,rootp);
fa[idx[p]]=rootq;
sum[rootq]+=p;
num[rootq]++;
}
}
inline void print()
{
int p;
scanf("%d",&p);
int rootp=find(idx[p]);
printf("%d %lld\n",num[rootp],sum[rootp]);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
while(m--)
{
int action;
scanf("%d",&action);
switch(action)
{
case 1:Union();break;
case 2:move();break;
case 3:print();break;
}
}
}
}