对树上的路径进行操作是十分难处理的事情。一开始的思路主要针对于\(a_i<=15\)这一特殊性质上。于是考虑了\(a_i<=1\)的情况,然而除了糊出一个适用范围极小的结论外,并没有什么用。

于是我瞄了一眼题解。令每一个点的值为所有与它相邻的边的权值的异或和。那么,我们发现,对于路径上的点,如果它不是端点,那么有两条与它相邻的的边异或上了相同的值,它的值不变;否则,它的值异或上这个值。并且,容易证明所有边权为零与所有点权为零是等价的。这样,各个结点的值都是无关的,树的结构是无意义的。问题转化成了在一个数列中,每次选取两个数异或上一个相同的值,以最少的操作次数使得数列中所有数为零。

然后,我们发现,对于每一次操作,所选取的数的异或和是不变的。假设这个数列是一个\(n\)个节点的图,而每一次操作都是往里面连边,那么最终每一个联通分量内的数异或和为零。并且,对于所有异或和为零的联通分量,一定存在操作次数为其大小减一的方案,即一个个异或过来,这正对应树的边数。那么,我们得到答案就是\(n-\)联通分量数。

那么,我们可以贪心地把所有值为零的结点单独分为一个联通分量,把两个值相同的结点分为一个联通分量。那么,一共就只有15种取值,每种取值最多1个,总状态数是\(2^{15}\)。于是可以状压dp,转移时我们枚举子集就可以了。

时间复杂度\(O(3^{15})\)。

#include <bits/stdc++.h>
using namespace std;
const int TOT = 1 << 15, N = 100010;
int dp[TOT],n,val[N],cnt[16],ans,sta,res[TOT];
int main() {
int a,b,c,tmp;
scanf("%d",&n);
for (int i = 1 ; i < n ; ++ i) {
scanf("%d%d%d",&a,&b,&c);
a++, b++;
val[a] ^= c;
val[b] ^= c;
}
for (int i = 1 ; i <= n ; ++ i)
++ cnt[val[i]];
ans = n;
ans -= cnt[0];
for (int i = 1 ; i <= 15 ; ++ i)
ans -= cnt[i]/2, sta |= (cnt[i]&1) << i >> 1;
for (int i = 0 ; i < TOT ; ++ i) {
tmp = 0;
for (int j = 1 ; j <= 15 ; ++ j)
if ((i >> j-1)&1) tmp ^= j;
res[i] = tmp;
}
for (int i = 1 ; i < TOT ; ++ i) {
for (int j = i ; j ; j = (j-1) & i)
if (!res[j]) dp[i] = max(dp[i],dp[i^j] + 1);
}
ans -= dp[sta];
printf("%d\n",ans);
return 0;
}

小结:这种代码简单但思想巧妙的题目是十分惊艳的,可惜为数不多。

【做题】apc001_f-XOR Tree——巧妙转化及dp的更多相关文章

  1. 【做题】spoj4060 A game with probability——dp

    赛前做题时忽然发现自己概率博弈类dp很弱,心好慌.(获胜概率或最优解期望) 于是就做了这道题,续了特别久. 一开始列dp式子的时候就花了很长时间,首先搞错了两次,然后忘记了根据上一轮dp值直接确定选什 ...

  2. 【做题】arc070_f-HonestOrUnkind——交互+巧妙思维

    做的第一道交互题-- 首先,有解的一个必要条件是\(a>b\).否则,即当\(a<=b\)时,可以有\(a\)个unkind的人假装自己就是那\(a\)个honest的人.(彼此之间都说是 ...

  3. 【做题】CSA49F - Card Collecting Game——思维&dp

    原文链接 https://www.cnblogs.com/cly-none/p/CSA49F.html 题意:Alice和Bob在玩游戏.有\(n\)种卡牌,每种卡牌有\(b_i\)张,保证\(\su ...

  4. 【做题】TCSRM592 Div1 500 LittleElephantAndPermutationDiv1——计数&dp

    题意:定义函数\(f(A,B) = \sum_{i=1}^n \max(A_i,B_i)\),其中\(A\)和\(B\)都是长度为\(n\)的排列.给出\(n\)和\(k\),问有多少对\((A,B) ...

  5. AtCoder Grand Contest 11~17 做题小记

    原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-11-to-20.html UPD(2018-11-16): ...

  6. AtCoder Grand Contest 1~10 做题小记

    原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-1-to-10.html 考虑到博客内容较多,编辑不方便的情 ...

  7. (转)poj算法做题顺序

    初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. (5)构造法.(poj329 ...

  8. 「AGC035C」 Skolem XOR Tree

    「AGC035C」 Skolem XOR Tree 感觉有那么一点点上道了? 首先对于一个 \(n\),若 \(n\equiv 3 \pmod 4\),我们很快能够构造出一个合法解如 \(n,n-1, ...

  9. LCT做题笔记

    最近几天打算认真复习LCT,毕竟以前只会板子.正好也可以学点新的用法,这里就用来写做题笔记吧.这个分类比较混乱,主要看感觉,不一定对: 维护森林的LCT 就是最普通,最一般那种的LCT啦.这类题目往往 ...

随机推荐

  1. day1 hbuilder的使用

    一.互联网的原理 1.概述 html:用来制作网页. 互联网原理:上网即请求数据. 用户通过在浏览器上输入一个网址,通过HTTP协议向服务器发送请求,服务器做出响应,将相关的网页数据传输到本地计算机, ...

  2. sitecore系统教程之部署架构方式分析

    当您第一次部署Sitecore体验平台时,您可以选择三种主要体系结构选项: 内部部署服务器解决方案 混合服务器方案 云服务器解决方案 您是选择将Sitecore作为云,内部部署还是混合解决方案运行,取 ...

  3. arc 092D Two Sequences

    题意: 给出两个长度N相同的整数序列A和B,有N^2种方式从A中选择一个数Ai,从B中选择一个数Bj,让两个数相加,求这N^2个数的XOR,即异或. 思路: 暴力的求显然是会超时的,因为是异或,就考虑 ...

  4. 【Hadoop学习之三】Hadoop全分布式安装

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop3.1.1 全分布式就是集群,注意配置主机名. ...

  5. 大数据处理框架之Strom:容错机制

    1.集群节点宕机Nimbus服务器 单点故障,大部分时间是闲置的,在supervisor挂掉时会影响,所以宕机影响不大,重启即可非Nimbus服务器 故障时,该节点上所有Task任务都会超时,Nimb ...

  6. Sqoop与HDFS、Hive、Hbase等系统的数据同步操作

    Sqoop与HDFS结合 下面我们结合 HDFS,介绍 Sqoop 从关系型数据库的导入和导出. Sqoop import 它的功能是将数据从关系型数据库导入 HDFS 中,其流程图如下所示. 我们来 ...

  7. Firefox 功能笔记

    1.复制标签 说明:复制标签功能即新开一个与当前页一样的标签页,这个功能在Chrome中点击标签右键复制即可,但是在firefox中没有 Firefox中实现:Ctrl+拖动标签页

  8. flask 使用Flask-WTF处理表单

    使用Flask-WTF处理表单 扩展Flask-WTF继承了WTFforms,使用它可以在flask中更方便的使用WTForms.Flask-WTF将表单数据解析.CSRF保护.文件上传等功能与Fla ...

  9. Vuejs vm对象详解

    Vuejs vm对象详解 vue数据是怎么驱动视图的?一堆数据放在那里是不会有任何作用的,它必须通过我们的View Model(视图模型)才能操控视图. 图中的model其实就是数据,一般我们写成js ...

  10. go语言,golang学习笔记4 用beego跑一个web应用

    go语言,golang学习笔记4 用beego跑一个web应用 首页 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/ 更新的命令是加个 -u 参数,g ...