汕头市赛srm1X T3
给n<=100000个点的树,每个点有一个01串,长度m<=200,串的可以随时01取反,串的每一位对应权Vi,从根节点到某个节点经过决定哪些串取反后取得的最大价值为某个点的权值,求:在这棵树上乱走,不能走权相同的相邻两点,每个长度D的简单路径的方案数。
题目很奇怪。结论很不显然。TJM和HR大佬很强。
首先,最后遍历的树的深度不会超过logm。在树上每走一步,都可以把0的个数减少至少一半。
其次,未达到最大值的两个点权值肯定不同。道理同上。因此把目标转化为“在权值未满的树上走”,重点在如何找出这棵树。
再者,Mi表示属性i的选择情况,在n个串中,当且仅当所有的Mi取遍2^n种集合时没有最优方案,最优方案即所有属性都取得到。在这m个选择情况中若取遍2^n种集合,则有全为0的Mi,必须把它某一位对应的串取反,但这意味着那个“只有这一位为0的选择情况”不合法,我们要选另一位,这样一直搞下去,所有的串都取反了,那那些全为1的Mi就gg了。
最后,在n个串中,若Mi没取遍2^n种集合,一定可以构造出最优方案。方法即把不存在的某个选择情况的1的位取反。这时除非某个选择情况与不存在的那种完全相同,否则必然会有一位为1。
于是,两次dfs解决。第二次dfs的统计方案易错,注意一下。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<math.h>
//#include<iostream>
using namespace std; int n,m;
#define maxn 100011
char s[];bool mp[maxn][];
struct Edge{int to,next;};
int vis[],state[];
#define LL long long
LL dis[][],ans[];
struct Tree
{
Edge edge[maxn<<];
int first[maxn],le;
Tree() {le=;}
void in(int x,int y)
{
edge[le].to=y;
edge[le].next=first[x];
first[x]=le++;
}
void dfsfirst(int x,int dep)
{
int tot=(<<dep);
for (int i=;i<=m;i++)
{
if (mp[x][i]) state[i]|=<<(dep-);
if (vis[state[i]]!=x) tot--,vis[state[i]]=x;
}
if (tot) first[x]=;
for (int i=first[x];i;i=edge[i].next)
dfsfirst(edge[i].to,dep+);
for (int i=;i<=m;i++)
if (mp[x][i]) state[i]^=<<(dep-);
}
void dfsfirst()
{
memset(vis,,sizeof(vis));
dfsfirst(,);
}
void dfssec(int x,int dep)
{
memset(dis[dep],,sizeof(dis[dep]));
dis[dep][]=dis[dep][]=;
for (int i=first[x];i;i=edge[i].next)
{
dfssec(edge[i].to,dep+);
for (int j=dep+;j<=;j++)
for (int k=dep+;k<=;k++)
ans[j+k-dep-dep]+=dis[dep][j-dep]*dis[dep+][k-dep];
for (int j=;j<=-dep-dep;j++) dis[dep][j+]+=dis[dep+][j];
}
}
void dfssec() {dfssec(,);}
}t;
int x;
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++)
{
scanf("%s",s);
for (int j=;j<m;j++) mp[i][j+]=s[j]-'';
}
for (int i=;i<=m;i++) scanf("%d",&x);
for (int i=;i<=n;i++) scanf("%d",&x),t.in(x,i);
t.dfsfirst();
memset(ans,,sizeof(ans));
t.dfssec();
int i;
for (i=;i>=;i--) if (ans[i]) break;
printf("%d ",n);
for (int j=;j<=i;j++) printf("%lld ",ans[j]);
return ;
}
汕头市赛srm1X T3的更多相关文章
- 汕头市队赛SRM14 T3覆盖
我们可以考虑两种情况 区间之间不相重叠 和 重叠 f[i][j]表示以当前最后一个区间以 i 结尾 并且选了 j 个区间 不相重叠的话 只要选 1-i-w 的max再加上 包含i在内的前四个数的和 相 ...
- 汕头市队赛 SRM13 T3
这道题可以贪心 维护一个答案队列 枚举位置 每次将比当前位置大的队尾全部替代掉 记录删了多少了就好了 #include<cstdio> #include<iostream> # ...
- 汕头市队赛 SRM1X T2 ——扫描线
绵津见-终 SRM 13 背景 “西瓜也是可以种在海上的!”——绵津见 然而种在海上的西瓜最需要防范的,是时不时会涌向瓜田的阵阵海浪. 幸好,身为海神的绵津见可以释放魔法“水平如镜”来阻止海浪拍打西瓜 ...
- 汕头市队赛 SRM1X T1
木之本樱 背景 “西瓜是可以种在树上的!”——木之本樱 描述 空地上,一排排的西瓜树拔地而起. 魔法世界里,空地是无限大的.所有的树排成了n条直线,每条直线也是向左右两端无限延伸的. 由于自己姓木(之 ...
- 汕头市队赛 SRM10 T3 数学上来先打表
数学上来先打表 SRM 10 描述 给出 n个点(不同点之间有区别),求出满足下列条件的连边(双向边)方案:1.每条边连接两个不同的点,每两个点之间至多有一条边2.不存在三个点a,b,c使三个点间两两 ...
- 洛谷noip 模拟赛 day1 T3
T7983 大芳的逆行板载 题目背景 大芳有一个不太好的习惯:在车里养青蛙.青蛙在一个n厘米(11n毫米s)的Van♂杆子上跳来跳去.她时常盯着青蛙看,以至于突然逆行不得不开始躲交叉弹.有一天他突发奇 ...
- 「2018-12-02模拟赛」T3 约束排列 解题报告
3.约束排列(place.pas/cpp/in/out) 问题描述: 给出 n 个互不相同的小写字母,表示出现的字符类型,以及 k 个约束关系: .....,表示 ai 必须出现在 bi 前面(ai, ...
- 雅礼 noip2018 模拟赛 day3 T3
典型树形dp 这里,我们应该看到一些基本性质: ①:如果这个边不能改(不是没有必要改),我们就不改,因为就算改过去还要改回来,显然不是最优的 注意:"不能改"是指边的性质和要求的相 ...
- war2 洛谷模拟赛day2 t3 状压
(new ) war2 题解:总体数据而言,我们很容易想到着就是DP啊,我们DP数组,用状态压缩,代表有那些点已经被占领过了,代表上一次我占的是那个.对于每一次状态转移,若当前我们要占领的Port ...
随机推荐
- 获取第三方软件的包名、入口Activity的类名
要启动指定的第三方软件,需要知道第三方软件的包名.类名. 获取第三方软件包名.类名的两种方法: 1.使用aapt aapt是sdk自带一个工具,在 Sdk\builds-tools 目录下 .如果没有 ...
- logging模块基础
很多程序都有记录日志的需求,日志不仅可以保存访问记录,也可以有错误,警告等信息输出. python的logging模块提供了标准的日志接口,可以通过logging存储各种格式的日志.logging模块 ...
- Debian9镜像安装问题
Debian9下载地址 https://www.debian.org/distrib/ Debian9有三个镜像文件 第一个包含系统2.3两个主要是一些软件的安装包只需下载第一个安装系统即可 默认安装 ...
- SqlServer2005使用top 100 PERCENT 无法排序的问题
由于公司提供的分页控件需要我使用top子句,而且有必要将查询到的记录全部取出,确发现不能排序,sql语句如下: SELECT TOP 15 * FROM( SELECT TOP (100) PERCE ...
- 一个JSON字符串和文件处理的命令行神器jq,windows和linux都可用
这个命令行神器的下载地址:https://stedolan.github.io/jq/# Windows和Linux版本均只有两个可执行文件,大小不过2MB多. 以Windows版本为例,介绍其用法. ...
- mysql 函数tree状
// 子节点的查询 CREATE DEFINER = `root`@`%` FUNCTION `getDeptChildList`(rootId BIGINT) RETURNS longtext DE ...
- linux ABORT的应用详解
NAME ABORT - 退出当前事务 SYNOPSIS ABORT [ WORK | TRANSACTION ] DESCRIPTION 描述 ABORT 回卷当前事务并且废弃所有当前事务中做的更新 ...
- Jquery中children与find之间的区别
<table id="tb"> <tr> <td>0</td> <td>1</td> <td>2 ...
- Redis那些事(一) — Redis简介
本人最近在学习Redis的使用和底层原理,有一些收获,所以希望通过写博客的形式来记录自己的学习过程,加深自己的理解,同时也方便以后查阅复习.目前打算先记录一些基本的使用方法和部分底层实现,其他的如果有 ...
- Educational Codeforces Round 59 (Rated for Div. 2) (前四题)
A. Digits Sequence Dividing(英文速读) 练习英语速读的题,我还上来昏迷一次....只要长度大于2那么一定可以等于2那么前面大于后面就行其他no 大于2的时候分成前面1个剩下 ...