Codeforces Round #527 (Div. 3)ABCF总结

这一场真是自闭场,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;
}

猜你喜欢

转载自blog.csdn.net/LSD20164388/article/details/85091118