• [atAGC007E]Shik and Travel


    二分枚举答案,判定答案是否合法

    贪心:每一个叶子只能经过一遍,因此叶子的顺序一定是一个dfs序,即走完一棵子树中的所有叶子才会到子树外

    根据这个贪心可以dp,设$f[k][l][r]$表示仅考虑$k$的子树,$l$和$r$为第一个和最后一个叶子到根的距离,时间复杂度大约有$o(n^{4或5})$,无法通过

    考虑优化,将所有$f[k][l][r]=1$的$(l,r)$记录下来,若存在$l'le l$且$r'le r$,$(l,r)$一定没有意义,这可以用一个单调栈来维护,那么同一个$l/r$所对应的$r/l$最多只有1个

    转移考虑合并,不妨假设左子树比右子树小,枚举左子树中的$(l_{1},r_{1})$,对于右子树中的$(l_{2},r_{2})$,有两种转移的可能:1.若$r_{1}+l_{2}+v_{ls}+v_{rs}le ans$,转移到$(l_{1}+v_{ls},r_{2}+v_{rs})$;2.若$l_{1}+r_{2}+v_{ls}+v_{rs}le ans$,转移到$(l_{2}+v_{rs},r_{1}+v_{ls})$

    可以利用单调性来优化,即找到满足$l_{2}le ans-r_{1}-v_{ls}-v_{rs}$且$r_{2}$最小的位置(第一种转移),那么每一组$(l_{1},r_{1})$最多转移到$k$中的两个状态(反之同理),即有$|state[k]|le 2min(|state[ls]|,|state[rs]|)$,空间复杂度为$o(nlog_{2}n)$,时间复杂度即为空间复杂度乘上二分,为$o(nlog^{ 2}_{2}n)$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define ll long long
     5 #define fi first
     6 #define se second
     7 vector<pair<ll,ll> >v,f[N];
     8 int n,x,ls[N],rs[N],w[N];
     9 ll ans;
    10 void dfs(int k){
    11     f[k].clear();
    12     if ((!ls[k])&&(!rs[k])){
    13         f[k].push_back(make_pair(0,0));
    14         return;
    15     }
    16     dfs(ls[k]);
    17     dfs(rs[k]);
    18     ll s=ans-w[ls[k]]-w[rs[k]];
    19     for(int i=0,j=0;i<f[ls[k]].size();i++){
    20         while ((j<f[rs[k]].size())&&(f[rs[k]][j].fi<=s-f[ls[k]][i].se))j++;
    21         if ((j)&&(f[rs[k]][j-1].fi<=s-f[ls[k]][i].se))f[k].push_back(make_pair(f[ls[k]][i].fi+w[ls[k]],f[rs[k]][j-1].se+w[rs[k]]));
    22     }
    23     swap(ls[k],rs[k]);
    24     for(int i=0,j=0;i<f[ls[k]].size();i++){
    25         while ((j<f[rs[k]].size())&&(f[rs[k]][j].fi<=s-f[ls[k]][i].se))j++;
    26         if ((j)&&(f[rs[k]][j-1].fi<=s-f[ls[k]][i].se))f[k].push_back(make_pair(f[ls[k]][i].fi+w[ls[k]],f[rs[k]][j-1].se+w[rs[k]]));
    27     }
    28     if (!f[k].size())return;
    29     sort(f[k].begin(),f[k].end());
    30     v.clear();
    31     v.push_back(f[k][0]);
    32     for(int i=1;i<f[k].size();i++)
    33         if (f[k][i].se<v[(int)v.size()-1].se)v.push_back(f[k][i]);
    34     f[k]=v;
    35 }
    36 bool pd(ll k){
    37     ans=k;
    38     dfs(1);
    39     return f[1].size();
    40 }
    41 int main(){
    42     scanf("%d",&n);
    43     for(int i=2;i<=n;i++){
    44         scanf("%d%d",&x,&w[i]);
    45         if (!ls[x])ls[x]=i;
    46         else rs[x]=i;
    47     }
    48     ll l=0,r=1LL*N*N;
    49     while (l<r){
    50         ll mid=(l+r>>1);
    51         if (pd(mid))r=mid;
    52         else l=mid+1;
    53     }
    54     printf("%lld",l);
    55 } 
    View Code
  • 相关阅读:
    cosface: large margin cosine loss for deep face recognition
    Max-Mahalanobis Linear Discriminant Analysis Networks
    AT-GAN: A Generative Attack Model for Adversarial Transferring on Generative Adversarial Nets
    Generating Adversarial Examples with Adversarial Networks
    IMPROVING ADVERSARIAL ROBUSTNESS REQUIRES REVISITING MISCLASSIFIED EXAMPLES
    ADAM : A METHOD FOR STOCHASTIC OPTIMIZATION
    Universal adversarial perturbations
    7.15
    Python爬虫之urllib模拟登录及cookie的那点事
    Http协议
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13820763.html
Copyright © 2020-2023  润新知