题目描述

求一棵 $[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. 实现Linux下dc的功能,计算后缀表达式的值

    提交测试截图和码云练习项目链接,实现Linux下dc的功能,计算后缀表达式的值 -将运算符写在两个操作数之后的表达式称为"后缀表达式",如上面的中缀表达式可转换为后缀表达式1 2 ...

  2. nginx重启无法找到PId的解决办法

    nginx停止的时候,出现了如下错误 nginx: [error] open() "/export/servers/nginx/logs/nginx.pid" failed (2: ...

  3. 记录使用jQuery和Python抓取采集数据的一个实例

    从现成的网站上抓取汽车品牌,型号,车系的数据库记录. 先看成果,大概4w条车款记录 一共建了四张表,分别存储品牌,车系,车型和车款 大概过程: 使用jQuery获取页面中呈现的大批内容 能通过页面一次 ...

  4. MSP430FR6972的串口波特率设置代码

    1. 本次使用ACLK,就是辅助时钟(32.768KHZ)作为串口的时钟源,那么使用波特率9600的时候,分频系数=32768/9600=3.41,所以是有小数位的,设置代码如下 UCA0CTLW0 ...

  5. JavaWeb(三十五)——使用JDBC处理Oracle大数据

    一.Oracle中大数据处理 在Oracle中,LOB(Large Object,大型对象)类型的字段现在用得越来越多了.因为这种类型的字段,容量大(最多能容纳4GB的数据),且一个表中可以有多个这种 ...

  6. 原生WebGL场景中绘制多个圆锥圆柱

    前几天解决了原生WebGL开发中的一个问题,就是在一个场景中绘制多个几何网格特征不同的模型,比如本文所做的绘制多个圆锥和圆柱在同一个场景中,今天抽空把解决的办法记录下来,同时也附上代码.首先声明,圆柱 ...

  7. 修改Linux系统下的最大文件描述符限制

    通常我们通过终端连接到linux系统后执行ulimit -n 命令可以看到本次登录的session其文件描述符的限制,如下: $ulimit -n1024 当然可以通过ulimit -SHn 1024 ...

  8. 【ML系列】简单的二元分类——Logistic回归

    对于了解机器学习中二元分类问题的来源与分析,我认为王树义老师这篇文章讲的非常好,通俗且易懂: http://blog.sciencenet.cn/blog-377709-1121098.html 但王 ...

  9. ThinkPHP - 6 - 学习笔记(2015.5.4)

    解决:OneThink 站点无法被友言uyan后台识别 打开友言uyan插件功能,但OneThink站点无法被友言uyan后台检测到.页面生成的uyan代码为: <!-- UY BEGIN -- ...

  10. 0428数字口袋精灵app优化

    "数字口袋精灵app"优化 目录: 一.项目github总仓库推送 二.开发成员 三.分工与合作 四.各模块成果 五.团队成员贡献分 内容: 一.项目github总仓库: http ...