这一场真是自闭场,2题10分钟开始挂机,ABC题意都没读明白,AB蒙了题意对了,C死活没读懂,蒙了好几发WA。电脑快没电的时候读了F题发现是个水题,可惜电量不够了。。。今天早上终于读懂了C题,然后秒A,然后F题也秒A。。。血亏。。。
D1D2目前没思路,待补。
A:我不知道题意是啥,看样例就是给你n,k(k<=26),把前k个字母依次输出一遍又一遍直到够n个字符就行。
B:我也不知道题意是啥,反正就是至少可以分成n/2对相同的数。所以排一遍序依次加相邻两个的差,跳两个就可以了。
C:赛后总算明白了题意:给你n-1个某串的前缀,长度分别为1~n-1,再给你n-1个某串的后缀,长度和前面一样。
现在这2*n-2个串的顺序乱了,让你输出给你的第i个串是前缀还是后缀。
读懂题意之后就是个水题,因为由最长的两个串就可以确定这个字符串了,然后瞎jb乱判一下就能过。
F:给你一棵树,树上每个节点的有值,你要选一个点,使所有其他点的权值*其他点到这个点的距离的和最大。
随便选一个点u为根,就可以发现每进入一颗以v节点为根的子树,权值变化为(val-dp[v]+dp[u]-dp[v])。(dp[v]为以v为根的子树的总权值)
我就不说名这个式子怎么来的了,很好推,自己想想就出来了。
所以两个dfs就ok了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn=200010;
int n,m,k;
ll dp[maxn],a[maxn];
ll ans,ct,cnt,tmp,flag;
vector<int>vc[maxn];
void dfs(int u,int fa,int dep)
{
dp[u]=a[u];
tmp+=a[u]*dep;
for(int i=0;i<vc[u].size();i++)
{
int v=vc[u][i];
if(v!=fa)
{
dfs(v,u,dep+1);
dp[u]+=dp[v];
}
}
}
void go(int u,int fa,ll val)
{
ans=max(ans,val);
for(int i=0;i<vc[u].size();i++)
{
int v=vc[u][i];
if(v!=fa) go(v,u,val-2*dp[v]+dp[1]);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
dp[i]=0;
vc[i].clear();
}
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
vc[x].push_back(y);
vc[y].push_back(x);
}
tmp=0;ans=0;
dfs(1,-1,0);
go(1,-1,tmp);
printf("%lld\n",ans);
return 0;
}