题目描述

求一棵 $[1,n]$ 的线段树的最大匹配数目与方案数。

$n\le 10^{18}$


题解

树形dp+记忆化搜索

设 $f[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配选择根节点的最大匹配&方案数,$g[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配不选择根节点的最大匹配&方案数。那么这是一个很普通的树形dp。

注意到区间长度相等的线段树的结果是一样的,且每层至多有两种区间长度不同的区间(参考 这题 ),因此直接以区间长度为状态进行记忆化搜索即可。

这里偷懒使用了map,时间复杂度 $O(\log^2 n)$

#include <map>
#include <cstdio>
#define mod 998244353
using namespace std;
typedef long long ll;
struct data
{
ll x , y;
data() {}
data(ll a , ll b) {x = a , y = b;}
data operator+(const data &a)const {return data(x + a.x , y * a.y % mod);}
data operator*(const data &a)const
{
if(x > a.x) return *this;
if(x < a.x) return a;
return data(x , (y + a.y) % mod);
}
};
struct node
{
data f , g;
node() {}
node(data a , data b) {f = a , g = b;}
};
map<ll , node> mp;
node dfs(ll n)
{
if(mp.find(n) != mp.end()) return mp[n];
node l = dfs(n - (n >> 1)) , r = dfs(n >> 1);
return mp[n] = node((l.f + r.g + data(1 , 1)) * (l.g + r.f + data(1 , 1)) * (l.g + r.g + data(1 , 2)) , (l.f + r.f) * (l.f + r.g) * (l.g + r.f) * (l.g + r.g));
}
int main()
{
mp[1] = node(data(-1 , 0) , data(0 , 1));
ll n;
scanf("%lld" , &n);
node tmp = dfs(n);
data ans = tmp.f * tmp.g;
printf("%lld %lld\n" , ans.x , ans.y);
return 0;
}

【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索的更多相关文章

  1. bzoj5123 [Lydsy12月赛]线段树的匹配

    题意: 线段树是这样一种数据结构:根节点表示区间 [1, n]:对于任意一个表示区间 [l, r] 的节点,若 l < r, 则取 mid = ⌊l+r/2⌋,该节点的左儿子为 [l, mid] ...

  2. [题解](树形dp/记忆化搜索)luogu_P1040_加分二叉树

    树形dp/记忆化搜索 首先可以看出树形dp,因为第一个问题并不需要知道子树的样子, 然而第二个输出前序遍历,必须知道每个子树的根节点,需要在树形dp过程中记录,递归输出 那么如何求最大加分树——根据中 ...

  3. 刷题总结——二叉苹果树(ssoj树形dp+记忆化搜索)

    题目: 题目背景 URAL:http://acm.timus.ru/problem.aspx?space=1&num=1018 题目描述 有一棵苹果树,如果树枝有分叉,一定是分 2 叉(就是说 ...

  4. 刷题总结——选课(ssoj树形dp+记忆化搜索+多叉树转二叉树)

    题目: 题目描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了 N(N<300)门的选修课程,每个学生可选课程的数量 M 是给定的.学生选修了这M门课 ...

  5. 加分二叉树 vijos1991 NOIP2003第三题 区间DP/树形DP/记忆化搜索

    描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一 ...

  6. BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP

    题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...

  7. CF700E Cool Slogans SAM、线段树合并、树形DP

    传送门 在最优的情况下,序列\(s_1,s_2,...,s_k\)中,\(s_i (i \in [2 , k])\)一定会是\(s_{i-1}\)的一个\(border\),即\(s_i\)同时是\( ...

  8. bzoj 5123: [Lydsy1712月赛]线段树的匹配

    设f[0/1][x]为区间[1,x]的根向下 不选(0)或者选(1)  的dp pair<最优值,方案数>. 可以很容易的发现总状态数就是log级别的,因为2*n 与 (2*n+1 或者 ...

  9. 牛客小白月赛13 小A买彩票 (记忆化搜索)

    链接:https://ac.nowcoder.com/acm/contest/549/C来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...

随机推荐

  1. 服务端调用接口API利器之HttpClient

    前言 之前有介绍过HttpClient作为爬虫的简单使用,那么今天在简单的介绍一下它的另一个用途:在服务端调用接口API进行交互.之所以整理这个呢,是因为前几天在测试云之家待办消息接口的时候,有使用云 ...

  2. 【LG3232】[HNOI2013]游走

    题面 洛谷 题解 代码 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstr ...

  3. 简单读取 properties文件

    看了网上很多读取的方法,都太过复杂,直接使用下面的方法就可以简单读取 properties文件了 ide使用idea 测试读取成功 import java.util.ResourceBundle; p ...

  4. 帮你理解学习lambda式

    概要     窗前明月光,疑是地上霜,举头望明月,低头思故乡.别误会这是开头诗与以下文章没任何关系. 今天我想给大家说道说道 C# lambda表达式,不废话,下面开始说道! lambda lambd ...

  5. html查漏补缺之meta标签

    什么是meta标签? meta标签是html标记head区的一个关键标签,它位于HTML文档的<head>和<title>之间(有些也不是在<head>和<t ...

  6. Elastic-Job 分布式调度平台

    概述 referred:http://elasticjob.io/docs/elastic-job-lite/00-overview Elastic-Job是一个分布式调度解决方案,由两个相互独立的子 ...

  7. CsvHelper文档-6类型转换

    CsvHelper文档-6类型转换 CsvHelper使用类型转换器来转换string到对象,或者对象到string: ITypeConverter 类型转换器的结构,必须实现: public int ...

  8. linux上open-vswitch安装和卸载

    一. ovs 从源码编译安装: 安装依赖项: # apt-get install make # apt-get install gcc # apt-get install build-essentia ...

  9. [T-ARA/筷子兄弟][Little Apple]

    歌词来源:http://music.163.com/#/song?id=29753511 作曲 : 筷子兄弟 [作曲 : 筷子兄弟] 作词 : K-Smith [作词 : KSmith] 编曲 : 新 ...

  10. redis memcache 比较

    Redis与Memcached的区别 传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都 ...