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

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

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

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

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

换言之,假设合并后的二元组为$(p,x)$(其中$x\ge 0$,且若$x=0$则不妨令$p=1$),那么根据上述分析该点上的二元组即为$\begin{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}\ne 0$则无解,其中$rt$为根),两者等价性显然

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

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

若$\sum_{i=1}^{l}a_{i}\not\equiv 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|\right)$

最后一项可以看作$|0-z|$,那么显然取$z$为$S'_{i}$(其中$1\le i\le 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\n");
41 else{
42 for(int i=1;i<=n;i++)ans+=abs(g[i]);
43 printf("%lld\n",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\n");
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\n",ans);
71 return 0;
72 }
73 if (sum){
74 printf("-1\n");
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\n",ans);
85 return 0;
86 }

[atAGC004F]Namori的更多相关文章

  1. [Arc079F] Namori Grundy

    [Arc079F] Namori Grundy 题目大意: 一个有向弱联通环套树. 一个点的sg值等于出边连向点的sg值的mex. 试问是否有办法给每个点分配sg值? 试题分析 题目大意把一些难点跳过 ...

  2. 2017国家集训队作业[agc004f]Namori

    2017国家集训队作业[agc004f]Namori 题意: 给你一颗树或环套树,树上有\(N\)个点,有\(M\)条边.一开始,树上的点都是白色,一次操作可以选择一条端点颜色相同的边,使它的端点颜色 ...

  3. AGC004F Namori 树形DP、解方程(?)

    传送门 因为不会列方程然后只会树上的,被吊打了QAQ 不难想到从叶子节点往上计算答案.可以考虑到可能树上存在一个点,在它的儿子做完之后接着若干颜色为白色的儿子,而当前点为白色,只能帮助一个儿子变成黑色 ...

  4. 洛谷AT2046 Namori(思维,基环树,树形DP)

    洛谷题目传送门 神仙思维题还是要写点东西才好. 树 每次操作把相邻且同色的点反色,直接这样思考会发现状态有很强的后效性,没办法考虑转移. 因为树是二分图,所以我们转化模型:在树的奇数层的所有点上都有一 ...

  5. AT2046 Namori 图论

    正解: 解题报告: 传送门! 首先看数据范围可以发现要么是棵树要么是个奇环要么是个偶环 然后就分类讨论分别看下这几个情况 首先是棵树的 首先可以想到树的情况就是个二分图,所以不妨把颜色重定义,让奇数层 ...

  6. Atcoder:AGC004F Namori

    传送门 先考虑树,树是一个二分图. 看到是二分图并且每次是对两边的同色的点反色可以想到转化:让奇数层的点为黑,偶数为白,变成每次可以交换两个点的颜色. 把黑看成 \(-1\),白看成 \(1\),那么 ...

  7. 【ARC079F】Namori Grundy

    Description 题目链接 大意:给一张基环外向树.要求给每一个点确定一个值,其值为所有后继点的\(\text{mex}\).求是否存在确定权值方案. Solution 首先,对于叶子节点,其权 ...

  8. [arc079f] Namori Grundy 分类讨论

    Description 给给全有一个NN个点NN条边的有向图,点的的编号从11到NN 给给全的图有NN条边,形如:(p1,1),(p2,2),...,(pN,N)(p1,1),(p2,2),...,( ...

  9. 【agc004F】Namori

    Portal -->agc004F Solution  好神仙的转化qwq ​  首先我们可以先考虑\(m=n-1\)的情况下,也就是树的情况下要怎么做  我们可以将这个问题转化一下:我们对这颗 ...

随机推荐

  1. IL合集

    由于之前写的表达式树合集,未编写任何注释且是以图片的形式展现给大家,在这里向各位看官道歉了,接下来为大家奉上新鲜出炉的香喷喷的IL合集,后面会持续更新,各位看官点关注不迷路,之前答应的手写IOC以及多 ...

  2. Oracle-绑定执行计划

    一.绑定执行计划 Oracle存在某个SQL多个执行计划的情况,那么如何快速将Oracle 好的执行计划,绑定到不好的SQL上呢? 由于版本的演进,绑定执行计划在10g 一般使用sql profile ...

  3. jsonp和cors解决跨域

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.对于JSON大家应该是很了解了吧,不是很清楚的朋友可以去json.org上了解下,简单易懂. 1.什么是跨 ...

  4. 款阿里开源的 Java 诊断工具Arthas

    Arthas是什么鬼? Arthas是一款阿里巴巴开源的 Java 线上诊断工具,功能非常强大,可以解决很多线上不方便解决的问题. Arthas诊断使用的是命令行交互模式,支持JDK6+,Linux. ...

  5. 【c++ Prime 学习笔记】第12章 动态内存

    对象的生存期: 全局对象:程序启动时创建,程序结束时销毁 局部static对象:第一次使用前创建,程序结束时销毁 局部自动对象:定义时创建,离开定义所在程序块时销毁 动态对象:生存期由程序控制,在显式 ...

  6. 【数据结构与算法Python版学习笔记】树——相关术语、定义、实现方法

    概念 一种基本的"非线性"数据结构--树 根 枝 叶 广泛应用于计算机科学的多个领域 操作系统 图形学 数据库 计算机网络 特征 第一个属性是层次性,即树是按层级构建的,越笼统就越 ...

  7. 395.至少有 K 个重复字符的最长子串

    题目 给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不少于k .返回这一子串的长度. 示例 1: 输入:s = "aaabb" ...

  8. AIApe问答机器人Scrum Meeting 4.25

    Scrum Meeting 2 日期:2021年4月25日 会议主要内容概述:前后端针对WebAPI进行协调与统一工作,商量接下来两日计划:敲定部分设计细节. 一.进度情况 组员 负责 两日内已完成的 ...

  9. elasticsearch入门(简单的crud操作)

    记录一下,elasticsearch从创建索引到插入数据的一个crud操作. 一.创建索引 curl -XPUT "http://192.168.99.1:9200/productindex ...

  10. 笔记本加装SSD并装系统

    1,首先了解笔记本配置信息 一般加装SSD都是120~256左右,并使用原有的机械硬盘:首先确定加装位置:1,是否支持M.2接口:假如支持,可以直接购买,拆机装上:我的笔记本不支持:所以考虑2,光驱的 ...