【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5735

【题目大意】

  给出一棵树,树上每个节点都有一个权值w,w不超过216,树的根为1,从一个点往根的方向走,可以得到他的祖先序列,现在需要从v1点的祖先序列中挑选出一定数量的点,组成数列v1,v2,v3……vm,要求vi是vi-1的祖先,求dp[v1]=max(dp[vi]+(w[v1] opt w[vi])),opt是一种运算,在题目中可为xor,or或者and,最后求出ans=sum_{i=1}^{n}(i*(w[i]+dp[i]))

【题解】

  对于这道题,我们首先考虑它的简化版本,在一个一维数组上求dp[i]=max(dp[j]+(w[i] opt w[j])) (j<i),显然枚举前缀的O(n2)的用脚趾头都能想出来的算法,出题人是不会给过的。那么我们观察一下题目,发现一个很奇巧的东西,w的值不超过216,难道说每次计算以w结尾的dp最大值,然后枚举二进制?一次6w多的计算量,明显也没有产生太大的优化,顺着这个思路下去,这道题采用了一种拆值DP的神奇的方式,

  dp[i]=max(dp[j]+([w[i]前八位]opt[w[j]前八位])<<8+[w[i]后八位]opt[w[j]后八位])

  记dp[A][B]=以前八位为A结尾,后八位以B结尾的dp值,于是就可以发现:

dp[A][B]=max(dp[i][B]+([w[i]前八位]opt[w[A]前八位])<<8)

  那么,在知道了后八位的情况下,前八位就能轻松dp,既然这样,那我们就在计算完每个节点之后,预处理后八位的dp值:

dp[A][i]=max(dp[A][j]+([w[i]后八位]opt[w[j]后八位]))

  这样子每次转移所需要的复杂度就只有28,可以接受。顺利完成。

  而这道题所处理的却是树上的问题,那么在每条链上DP的过程中预处理祖先节点dp数组,按照上述方法计算子节点的dp值即可,而对于不同的子节点,dp数组备份,然后回溯即可。

【代码】

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef unsigned int UI;
const int N=65540,mod=1e9+7;
UI T,n,i,w[N],nxt[N],x,f[256][256],tmp[N][256],v[256],ans;
vector<UI>g[N];
char op[5];
UI opt(UI a,UI b){
if(op[0]=='A')return a&b;
if(op[0]=='O')return a|b;
if(op[0]=='X')return a^b;
}
void dfs(UI x){
UI dp=0,A=w[x]>>8,B=w[x]&255;
for(int i=0;i<256;i++)if(v[i])dp=max(dp,f[i][B]+(opt(A,i)<<8));
ans=(1LL*x*(dp+w[x])+ans)%mod;
for(v[A]++,i=0;i<256;i++)tmp[x][i]=f[A][i],f[A][i]=max(f[A][i],opt(B,i)+dp);
for(int i=0;i<g[x].size();i++)dfs(g[x][i]);
for(v[A]--,i=0;i<256;i++)f[A][i]=tmp[x][i];
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %s",&n,op);
for(int i=1;i<=n;i++)scanf("%d",&w[i]),g[i].clear();
for(int i=2;i<=n;i++)scanf("%d",&x),g[x].push_back(i);
ans=0; dfs(1);
printf("%d\n",ans);
}return 0;
}

  

HDU 5735 Born Slippy(拆值DP+位运算)的更多相关文章

  1. hdu 5735 Born Slippy 暴力

    Born Slippy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5735 Description Professor Zhang has a r ...

  2. HDU 5735 - Born Slippy

    题意: 一棵 n 个节点的根树,i 节点权重 wi 对每一个节点s,找到这样一个长 m 的标号序列 v : 1. vi是vi-1 的祖先 2. f[s] = w[vi] + ∑(i=2, m) (w[ ...

  3. hdu 4336 Card Collector (概率dp+位运算 求期望)

    题目链接 Card Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  4. 求集合中选一个数与当前值进行位运算的max

    求集合中选一个数与当前值进行位运算的max 这是一个听来的神仙东西. 先确定一下值域把,大概\(2^{16}\),再大点也可以,但是这里就只是写写,所以无所谓啦. 我们先看看如果暴力求怎么做,位运算需 ...

  5. 基于DP+位运算的RMQ算法

    来源:http://blog.csdn.net/y990041769/article/details/38405063 RMQ算法,是一个快速求区间最值的离线算法,预处理时间复杂度O(n*log(n) ...

  6. HDU 1074 Doing Homework (动态规划,位运算)

    HDU 1074 Doing Homework (动态规划,位运算) Description Ignatius has just come back school from the 30th ACM/ ...

  7. HDU 3006 The Number of set(位运算 状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3006 题目大意:给定n个集合,每个集合都是由大于等于1小于等于m的数字组成,m最大为14.由给出的集合 ...

  8. [BZOJ1151][CTSC2007]动物园zoo 解题报告|DP|位运算

    Description 最近一直在为了学习算法而做题,这道题是初一小神犇让我看的.感觉挺不错于是写了写. 这道题如果是一条线的话我们可以构造一个DP f[i,j]表示以i为起点,i,i+1...i+4 ...

  9. HDU 2276 Kiki & Little Kiki 2(矩阵位运算)

    Kiki & Little Kiki 2 转载自:点这里 [题目链接]Kiki & Little Kiki 2 [题目类型]矩阵位运算 &题意: 一排灯,开关状态已知,每过一秒 ...

随机推荐

  1. linux 下eclipse配置apache服务器,选中server时server name为灰色状态

    后来发现,没有创建

  2. ThinkPHP+uploadify+upload+PHPExcel 无刷新导入数据

    前端HTML+JQuery  备注Jquery需要1.x版本,不能用2.x版本 1.引入必要文件及上传input <load file="__PUBLIC__/js/jquery-1. ...

  3. 轮播图插件myFocus使用

    myFocus官网下载源码,本文是v2.0.1版,解压后如下 将js包内文件拷入工程 在工程内引入 <script src="js/myfocus-2.0.1.min.js" ...

  4. 微信网页授权java实现

    功能:主要用于在用户通过手机端微信访问第三方H5页面时获取用户的身份信息(openId,昵称,头像,所在地等..)可用来实现微信登录.微信账号绑定.用户身份鉴权等功能.     开发前的准备: 1.需 ...

  5. 影响世界的IT

    MIT BBS上说微软电话面试的一道题就是"Who do you think is the best coder,and why?”.我觉得挺有意思的,也来凑个热闹.排名不分先后. 1.Bi ...

  6. 【Win7激活工具2013版下载】适用于旗舰版、家庭高级版等所有版本32/64位 OEM激活

    虽然现在Win8已经发布了,但是身边总是还有一些朋友在用着Win7系统,而近期微软频繁的推送补丁包,导致之前的那些激活都失效了.找了网络上很多工具,之前的那些有的已经不能用了,激活不了,今天就推荐一些 ...

  7. 使用百度语音识别REST API,做全平台语音识别

    百度语音开发介绍文档: http://yuyin.baidu.com/docs/asr# 使用语音识别,需要在百度申请一个应用,然后拿到API Key和Secret Key,然后才可以使用语音识别 p ...

  8. Android中使用HTTP服务

    在Android中,除了使用java.net包下的API访问HTTP服务之外,我们还可以换一种途径去完成工作.Android SDK附带了Apache的HttpClient API.Apache Ht ...

  9. 柯南君:看大数据时代下的IT架构(6)消息队列之RabbitMQ--案例(Publish/Subscribe起航)

    二.Publish/Subscribe(发布/订阅)(using the Java Client) 为了说明这个模式,我们将构建一个简单的日志系统.它将包括两个项目: 第一个将发出日志消息 第二个将接 ...

  10. openstack 采用conductor的原因

    供参考. Tan0同学给我的解释: 两个原因 一个是为了isolation做准备 因为升级主要就是升DB的schema 如果让compute直接读写DB,那每次升级都得升compute 现在隔离开之后 ...