1. 程式人生 > >Codeforces Round #530 (Div. 2) ABCD總結

Codeforces Round #530 (Div. 2) ABCD總結

本來四道題rank800+穩穩地上分,然後唯一一道1A的C題掛了終測,瞬間rank2000+,掉了49分。。。(哇)

A:給你雪球初始的重量和高度,每秒下降一米,每下降一米重量就會增加對應的高度。然後給你兩個x1,h1和x2,h2表示高度h1會讓雪球重量減少x1,高度h2會讓雪球重量減少x2(當然還是要增加對應高度),雪球最小重量為0,求到h=0的時候雪球的重量。

感覺這題真是無聊。。。簽到題還整這麼麻煩,記錄一下h1和h2,再一個for完事。

B:按照題目所給的圖那樣擺,問最少需要多少根木棒可以(通過補充)擺成n個正方形。

明顯是直接一橫一豎沿上方和左方擺。。。自己推一下公式,這道題的解法非常多。。。

C:真tm的坑,給你一個包含小寫字母和* ?的字串,保證* ?前面有字元。*可以刪除前面的字元或者保留前面的字元,或者把前一個字元複製任意次。?只能刪除前面的字元或者保留前面的字元。問你每個* ?選擇使用方式以後,是否能使字串長度為n。

坑點已經紅色標註了,如果只複製一次會!掛!終!測!(說多了都是淚)

統計一下 * 和 ?的數量,然後按題意進行填充或刪除即可。注意細節。

D:給你n-1個數a[i](2<=i<=n),表示i的祖先是a[i](無向邊,保證構成樹,1為根節點),然後給你n個數s[i]。

每個節點有權值,但是未知。

若i為奇數層節點,則s[i]為從根節點(1號節點)到i號節點的所有點的權值之和(包括第i個點),否則s[i]為-1。

現在請你給每個點賦權值,使所有節點的權值之和最小。如果不存在合法方案,輸出-1。

思路:

其實樹給了我們以後,只需一個dfs就很容易確定奇數層和偶數層的節點。

要使總權值最小,肯定是讓分支節點承擔儘可能大的值。

於是用一個dp陣列,

dp[i]=      s[i] i為奇數層節點

               min(dp[i],dp[v]) i為偶數層節點,v為i節點的直接子節點

然後再dfs一下,val表示根節點到當前節點的權值和,對於奇數層的點,如果s[i]<val,那顯然是-1了,否則令a[i]=val-s[i]。

對於偶數層的節點,如果dp[i]<val,顯然還是-1,否則如果dp[i]未賦值(偶數層的葉子結點)。則a[i]=0即可,否則a[i]=dp[i]-val(想想是不是)。注意long long。

程式碼:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn=200010;
int n,m,k,x,y;
ll a[maxn],s[maxn];
ll c[maxn],dp[maxn];
ll ans,ct,cnt,tmp,flag;
vector<int>vc[maxn];
void dfs(int u,int fa,int dep)
{
    c[u]=dep;
    if(dep&1) dp[u]=s[u];
    //if(dep&1) dp[u]=max(dp[u],s[u]);
    for(int i=0;i<vc[u].size();i++)
    {
        int v=vc[u][i];
        if(v==fa) continue;
        dfs(v,u,dep+1);
        if(dep%2==0)
        {
            dp[u]=min(dp[u],dp[v]);
        }
    }
    /*if(vc[u].size()==1)
    {
        if(dep%2==0) dp[u]=0;
    }*/
}
void dfs2(int u,int fa,int dep,ll val)
{
    //cout<<val<<" "<<u<<" "<<s[u]<<endl;
    //if((dep%2==0)&&vc[u].size()==1) return;
    //else if(u!=1&&(dep&1)&&vc[u].size()==1) {ans+=val;return;}
    if(dep&1)
    {
        if(val>s[u]) {flag=0;return;}
        else a[u]=s[u]-val;
    }
    else
    {
        if(dp[u]<val) {flag=0;return;}
        if(dp[u]==inf) a[u]=0;
        else a[u]=dp[u]-val;
    }
    ans+=a[u];
    //if(dep&1) dp[u]=max(dp[u],s[u]);
    for(int i=0;i<vc[u].size();i++)
    {
        int v=vc[u][i];
        if(v==fa) continue;
        dfs2(v,u,dep+1,val+a[u]);
    }
}
int main()
{
    int T,cas=1;
    scanf("%d",&n);
    flag=1;ans=0;
    for(int i=2;i<=n;i++)
    {
        scanf("%d",&m);
        vc[i].push_back(m);
        vc[m].push_back(i);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&s[i]);
        dp[i]=inf;
    }
    memset(c,0,sizeof(c));
    memset(a,0,sizeof(a));
    //memset(dp,0,sizeof(dp));
    dfs(1,-1,1);
    //for(int i=1;i<=n;i++)
    //cout<<dp[i]<<" "<<endl;
    dfs2(1,-1,1,0);
    if(!flag) puts("-1");
    else printf("%lld\n",ans);
      //  if(flag) puts("Yes"); else puts("No");
    return 0;
}