开始 2023-12-08 23:14:08

【2024省选前】20231208更正

结束 2023-12-31 00:00:00
Contest is over.
当前 2025-05-01 08:18:41

tree
#include<bits/stdc++.h>
using namespace std;
const int N=8e5+5;
const int mo=998244353;
int n,x,y,num,si,rt,tot,a[N],s[N],mx[N],dis[N],d[N],ans1[N],san[N],sum[N];
bool bz[N];
vector<int>p[N];
void findroot(int x,int y)
{
	s[x]=1,mx[x]=0;
	for (auto t:p[x])
	if (t^y && !bz[t])
	{
		findroot(t,x);
		s[x]+=s[t];
		mx[x]=max(mx[x],s[t]);
	}
	mx[x]=max(mx[x],si-s[x]);
	if (mx[x]<mx[rt]) rt=x;
}
void dg1(int x,int y)
{
	d[++tot]=x;
	for (auto t:p[x])
	if (t^y && !bz[t])
	{
		dis[t]=dis[x]+1;
		dg1(t,x);
	}
}
void calc(int f)
{
	memset(sum,0,sizeof(int)*(tot+1));
	for (int i=1;i<=tot;i++)
	if (d[i]<=n)
	{
		int x=a[d[i]]-dis[d[i]];
		x=min(x,tot);
		if (x>=0) sum[x]++;
	}
	for (int i=tot-1;i>=0;i--) sum[i]+=sum[i+1];
	for (int i=1;i<=tot;i++) ans1[d[i]]+=f*sum[dis[d[i]]];
}
void dg(int x)
{
	bz[x]=1;
	dis[x]=0;
	tot=0;
	dg1(x,0);
	calc(1);
	for (auto t:p[x])
	if (!bz[t])
	{
		dis[t]=1;
		tot=0;
		dg1(t,x);
		calc(-1);
		si=tot;
		rt=0;
		findroot(t,0);
		dg(rt);
	}
}
int main()
{
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
	ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    for (int i=1;i<=n;i++) cin>>a[i],a[i]*=2;
    num=n;
	for (int i=1;i<n;i++)
	{
		cin>>x>>y;
		num++;
		p[x].emplace_back(num);
		p[y].emplace_back(num);
		p[num].emplace_back(x);
		p[num].emplace_back(y);
	}
	mx[0]=1e9;
	si=num;
	findroot(1,0);
	dg(rt);
	san[0]=1;
	for (int i=1;i<=n;i++) san[i]=3ll*san[i-1]%mo;
	int ans=0;
	for (int i=1;i<=n;i++) ans=(ans+san[ans1[i]])%mo;
	for (int i=n+1;i<=num;i++) ans=(ans-san[ans1[i]]+mo)%mo;
	ans=(ans-1+mo)%mo;
	cout<<ans;
	return 0;
}


admin  •  1年前

比赛已结束。