异象石 wa 0分
查看原帖
异象石 wa 0分
25431
Ridiculous楼主2021/5/26 17:37

样例过了的,也开了ll,其实这道题打完自己思路也不是完全清除,有无dalao帮忙看看,感谢

#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=500005;
struct node
{
	int x,y,z;
}e[maxn];
int Head[maxn],Next[maxn];
int tm[maxn],dep[maxn],l0g2[maxn];
int f[maxn][60];
int M,cnt;
ll ans;
ll dist[maxn];
bool v[maxn];
struct nodecmp
{
	bool operator()(const int &x,const int &y)const
	{
		return tm[x]<tm[y];
	}
};
set<int,nodecmp>s;
typedef set<int,nodecmp>::iterator sit;
inline void insert(int i,int x,int y,int z)
{
	e[i].x=x;
	e[i].y=y;
	e[i].z=z;
	Next[i]=Head[x];
	Head[x]=i;
}
inline void swap(int &a,int &b)
{
	int t=a;
	a=b;
	b=t;
}
void dfs_init(int r,int fa)
{
	v[r]=true;
	tm[r]=++cnt;
	dep[r]=dep[fa]+1;
	f[r][0]=fa;
	for(int i=1;i<=l0g2[dep[r]];i++)
		f[r][i]=f[f[r][i-1]][i-1];
	for(int i=Head[r];i;i=Next[i])
	{
		int y=e[i].y;
		if(!v[y])
		{
			dist[y]=dist[r]+e[i].z;
			dfs_init(y,r);
		}
	}
}
int lca(int a,int b)
{
	if(dep[a]>dep[b])
		swap(a,b);
	while(dep[b]!=dep[a])
		b=f[b][l0g2[dep[b]-dep[a]]];
	if(a==b)
		return a;
	for(int i=l0g2[dep[a]];i>=0;i--)
		if(f[a][i]!=f[b][i])
		{
			a=f[a][i];
			b=f[b][i];
		}
	return f[a][0];
}
inline sit rig(sit i)
{
	if(++i==s.end())
		return s.begin();
	return i;
}
inline sit lef(sit i)
{
	if(i==s.begin())
		return --s.end();
	return --i;
}
inline ll dis(int l,int r)
{
	return dist[l]+dist[r]-2*dist[lca(l,r)];
}
inline ll diff(int t)
{
	sit i=s.find(t);
	sit r=rig(i);
	sit l=lef(i);
	return dis(t,*l)+dis(t,*r)-dis(*l,*r);
}
int main()
{
	//freopen("1.txt","r",stdin);
	int n,m;
	scanf("%d%d",&n,&m);
	for(register int i=2;i<=n;i++)
		l0g2[i]=l0g2[i>>1]+1;
	for(int x,y,z,i=1;i<n;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		insert(++M,x,y,z);
		insert(++M,y,x,z);
	}
	dfs_init(1,0);
	while(m--)
	{
		int t;
		scanf("%d",&t);
		if(s.count(t)!=0)
		{
			ans-=diff(t);
			s.erase(t);
		}
		else
		{
			s.insert(t);
			ans+=diff(t);
		}
		printf("%d\n",ans);
	}
	return 0;
}
``
2021/5/26 17:37
加载中...