• [atAGC004F]Namori


    考虑树的情况,将其以任意一点为根建树

    对于每一个节点,考虑其要与父亲操作几次才能使子树内均为黑色,这可以用形如$(0/1,x)$的二元组来描述,其中0/1即表示其要求操作时父亲是白色/黑色且要操作$x$次

    考虑一个叶子,其二元组显然为$(0,1)$,接下来每一个点即可以交替将儿子中的$(0/1,x)$变为$(0/1,x-1)$

    (先以白色点操作$(0,x)$,操作后变为黑色,再以黑色点操作$(1,x)$……)

    最终,将剩下的合并(第一元必然相同,第二元直接相加),那么该节点即需在另一个状态下与其父亲操作,另外最后还需要额外以白色操作一次

    换言之,假设合并后的二元组为$(p,x)$(其中$xge 0$,且若$x=0$则不妨令$p=1$),那么根据上述分析该点上的二元组即为$egin{cases}(1,x-1)&(p=0)\(0,x+1)&(p=1)end{cases}$

    关于答案,若根节点上的二元组第二维不为0显然无解,否则考虑每一个节点与父亲操作的次数,即为该点上二元组的第二维,显然将对所有节点求和即可

    时间复杂度为$o(n)$,可以通过

    事实上,上述二元组可以直接用一个整数描述,即将$(0/1,x)$分别看作$pm x$,则转移即$g_{i}=1-sum_{son}g_{son}$,最终答案也即$sum_{i}|g_{i}|$(特别的,若$g_{rt} e 0$则无解,其中$rt$为根),两者等价性显然

    考虑基环树的情况,将整个基环当作根,并删去基环上的边后得到若干棵子树(仍以基环上的点为根),对每一棵子树仍用上述方式计算得到根的$g_{i}$,最终即可得到一个长为$l$(其中$l$为环长)的序列

    记该序列为$a_{i}$,此时问题即将相邻两个$a_{i}$(注意首尾也相连)同时$pm 1$,并使得最终$a_{i}$均为0

    若$sum_{i=1}^{l}a_{i} otequiv 0(mod 2)$显然无解(操作不改变奇偶性),否则对$l$的奇偶性分类讨论:

    1.若$l$为奇数,考虑奇偶数位的差值,除了首尾操作以外不会改变该值,而首尾操作恰会使该值$pm 2$,由此不难确定首尾操作形式即次数,进而操作后将首尾断开,从前往后依次使得$a_{i}$为0即可(最终$a_{l}$一定为0)

    2.若$l$为偶数,注意到奇数位和偶数位差值不变,因此初始两者必须相同

    枚举首尾操作使得$a_{1}$和$a_{l}$同时减$z$,之后即将首尾断开并从前往后依次使得$a_{i}$为0

    不难得到(首尾断开后)$a_{i}$清0的代价即$sum_{i=1}^{l}abs{sum_{j=1}^{i}(-1)^{i-j}a_{j}}$,对每个$i$预处理出该值为$S_{i}$(减去$z$前),那么修改的影响即将奇数项减去$z$、偶数项(除$l$以外)加上$z$

    将$S_{i}$偶数项取相反数(奇数项不变)得到$S'_{i}$,此时即求$|S_{l}|+min_{z}left(sum_{i=1}^{l-1}|S'_{i}-z|+|z| ight)$

    最后一项可以看作$|0-z|$,那么显然取$z$为$S'_{i}$(其中$1le ile l-1$)和0的中位数即可

    时间复杂度也为$o(n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 #define ll long long
     5 vector<int>v0,v[N];
     6 int n,m,x,y,st[N],vis[N];
     7 ll sum,ans,a[N],g[N];
     8 void dfs(int k,int fa){
     9     st[++st[0]]=k,vis[k]=1;
    10     for(int i=0;i<v[k].size();i++)
    11         if (v[k][i]!=fa){
    12             if (!vis[v[k][i]])dfs(v[k][i],k);
    13             else{
    14                 if (vis[v[k][i]]==2)continue;
    15                 for(int j=st[0];st[j]!=v[k][i];j--)v0.push_back(st[j]);
    16                 v0.push_back(v[k][i]);
    17             }
    18         }
    19     st[0]--,vis[k]=2;
    20 }
    21 void dp(int k){
    22     vis[k]=g[k]=1;
    23     for(int i=0;i<v[k].size();i++)
    24         if (!vis[v[k][i]]){
    25             dp(v[k][i]);
    26             g[k]-=g[v[k][i]];
    27         }
    28 }
    29 int main(){
    30     scanf("%d%d",&n,&m);
    31     for(int i=1;i<=m;i++){
    32         scanf("%d%d",&x,&y);
    33         v[x].push_back(y);
    34         v[y].push_back(x);
    35     }
    36     dfs(1,0);
    37     memset(vis,0,sizeof(vis));
    38     if (v0.empty()){
    39         dp(1);
    40         if (g[1])printf("-1
    ");
    41         else{
    42             for(int i=1;i<=n;i++)ans+=abs(g[i]);
    43             printf("%lld
    ",ans);
    44         }
    45         return 0;
    46     }
    47     int l=v0.size();
    48     for(int i=0;i<l;i++)vis[v0[i]]=2;
    49     for(int i=0;i<l;i++){
    50         dp(v0[i]);
    51         a[i+1]=g[v0[i]];
    52     }
    53     for(int i=1;i<=n;i++)ans+=abs(g[i]);
    54     for(int i=1;i<=l;i++){
    55         ans-=abs(a[i]);
    56         if (i&1)sum+=a[i];
    57         else sum-=a[i];
    58     }
    59     if (sum&1){
    60         printf("-1
    ");
    61         return 0;
    62     }
    63     if (l&1){
    64         ans+=(abs(sum)>>1);
    65         a[1]-=(sum>>1),a[l]-=(sum>>1);
    66         for(int i=1;i<l;i++){
    67             ans+=abs(a[i]);
    68             a[i+1]-=a[i];
    69         }
    70         printf("%lld
    ",ans);
    71         return 0;
    72     }
    73     if (sum){
    74         printf("-1
    ");
    75         return 0;
    76     }
    77     for(int i=1;i<=l;i++)a[i]-=a[i-1];
    78     ans+=abs(a[l]),a[l]=0;
    79     for(int i=2;i<=l;i+=2)a[i]=-a[i];
    80     sort(a+1,a+l+1);
    81     for(int i=1;i<=l;i++)
    82         if (i<=(l>>1))ans+=a[l>>1]-a[i];
    83         else ans+=a[i]-a[l>>1];
    84     printf("%lld
    ",ans);
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    Java RandomAccessFile与MappedByteBuffer
    Apache httpClient
    gitolite migration to bitbucket
    logback身份证脱敏
    身份证号码-正则表达式
    webservice-整理
    Java高编译低运行错误(ConcurrentHashMap.keySet)
    IIS(互联网信息服务)
    ASP.NET MVC:UrlHelper.cs
    TortoiseSVN 和 VisualSVN
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15438467.html
Copyright © 2020-2023  润新知