题意:

线段树是这样一种数据结构:根节点表示区间 [1, n];对于任意一个表示区间 [l, r] 的节点,若 l < r,

则取 mid = ⌊l+r/2⌋,该节点的左儿子为 [l, mid],右儿子为 [mid + 1, r];若 l = r,则它为叶子。

一棵树的匹配是指一个树边集合,满足任意两条边没有公共端点。一棵树的最大匹配是指所有合法

匹配方案中,所选树边最多的匹配方案。

给定一棵表示 [1, n] 的线段树,请求出它的最大匹配中有多少条边,并求出有多少种最大匹配的方

案。因为答案很大,请对 998244353 取模输出。

Input

第一行包含一个正整数 n(1 ≤ n ≤ 1018)。

Output

输出一行两个整数,第一个表示最大匹配中的边数,第二个表示方案数对 998244353 取模的结果。

f[n]表示大小为n的线段树的最大匹配数,g[n]表示方案数.

结论:线段树每一层的节点大小最多有两种.

如果上一层有2k,2k-1,那下一层就有k,k-1.如果上一层有2k,2k+1,那么下一层就有k,k+1.反正最多两种.

层数logn,那么有用状态2logn个,200不到,map开dp数组+记忆化搜索,完事.

#include<cstdio>
#include<map>
using namespace std;
typedef long long ll;
const ll mod=998244353;
map<ll,ll> f0,f1;
map<ll,ll> g0,g1;
ll f(ll n){
if(n==1)return 0;
if(f1[n])return 0;
ll l=n/2,r=n-n/2;
f(l);f(r);
f0[n]=max(f0[l],f1[l])+max(f0[r],f1[r]);
f1[n]=1+max(f0[l]+max(f0[r],f1[r]),f0[r]+max(f0[l],f1[l]));
ll ans0=0,ans1=0;
if(f0[l]==f1[l])ans0=g0[l]+g1[l];
else if(f0[l]<f1[l])ans0=g1[l];
else ans0=g0[l];
if(f0[r]==f1[r])ans1=g0[r]+g1[r];
else if(f0[r]<f1[r])ans1=g1[r];
else ans1=g0[r];
g0[n]=ans0*ans1%mod;
g1[n]=0;
if(f1[n]==f0[l]+max(f0[r],f1[r])+1)g1[n]+=g0[l]*1ll*ans1%mod;
if(f1[n]==f0[r]+max(f0[l],f1[l])+1)g1[n]+=g0[r]*1ll*ans0%mod;
g1[n]%=mod;
return max(f0[n],f1[n]);
}
int main(){
ll n;scanf("%lld",&n);
f0[1]=f1[1]=0;
g0[1]=1;g1[1]=0;
ll ans1=f(n);
ll ans2=0;
if(f0[n]==ans1)ans2=(ans2+g0[n])%mod;
if(f1[n]==ans1)ans2=(ans2+g1[n])%mod;
printf("%lld %lld\n",ans1,ans2);
return 0;
}

bzoj5123 [Lydsy12月赛]线段树的匹配的更多相关文章

  1. 【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索

    题目描述 求一棵 $[1,n]$ 的线段树的最大匹配数目与方案数. $n\le 10^{18}$ 题解 树形dp+记忆化搜索 设 $f[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配选择根 ...

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

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

  3. BZOJ5123 线段树的匹配(树形dp)

    线段树的任意一棵子树都相当于节点数与该子树相同的线段树.于是假装在树形dp即可,记忆化搜索实现,有效状态数是logn级别的. #include<iostream> #include< ...

  4. CF308C-Sereja and Brackets-(线段树+括号匹配)

    题意:给出一段括号,多次询问某个区间内能匹配多少括号. 题解:线段树,结构体三个属性,多余的左括号l,多余的右括号r,能够匹配的括号数val. 当前结点的val=左儿子的val+右儿子的val+min ...

  5. bzoj千题计划164:bzoj5123: 线段树的匹配

    http://www.lydsy.com/JudgeOnline/upload/201712/prob12.pdf dp[len][0/1] 表示节点表示区间长度为len,节点选/不选的 最大匹配 s ...

  6. 【BZOJ3413】匹配(后缀自动机,线段树合并)

    [BZOJ3413]匹配(后缀自动机,线段树合并) 题面 BZOJ 题解 很好的一道题目. 做一个转化,匹配的次数显然就是在可以匹配的区间中,每个前缀的出现次数之和. 首先是空前缀的出现次数,意味着你 ...

  7. 【BZOJ4919】[Lydsy六月月赛]大根堆 线段树合并

    [BZOJ4919][Lydsy六月月赛]大根堆 Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切 ...

  8. 牛客网 牛客小白月赛5 I.区间 (interval)-线段树 or 差分数组?

    牛客小白月赛5 I.区间 (interval) 休闲的时候写的,但是写的心情有点挫,都是完全版线段树,我的一个队友直接就水过去了,为啥我的就超内存呢??? 试了一晚上,找出来了,多初始化了add标记数 ...

  9. [Bzoj5358][Lydsy1805月赛]口算训练(预处理+动态开点线段树)

    5358: [Lydsy1805月赛]口算训练 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 318  Solved: 105[Submit][Stat ...

随机推荐

  1. 关于homebrew使用时遇到的问题: Error: Could not symlink bin/gdb/usr/local/bin is not writable.

    # 关于homebrew使用时遇到的问题: Error: Could not symlink bin/gdb/usr/local/bin is not writable. 这是我在给我的Mac电脑安装 ...

  2. 20155338 2016-2017-2 《Java程序设计》第10周学习总结

    20155338 2016-2017-2 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程 · 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事 ...

  3. oracle-11g-64位安装和plaql

    1.oracle卸载 如果是新装,请跳过此步骤 卸载步骤: 1.停止所有服务 2.用自带删除软件,删除所有目录 3.打开注册表: -->运行regedit,删除HKEY_LOCAL_MACHIN ...

  4. SRM First Problem && SRM 638 250pts NamingConvention

    NamingConvention 题意: 给一个字符串,删掉所有的'_',然后将‘_'后的第一个字符改成大写. 代码: #include<bits/stdc++.h> using name ...

  5. ubuntu 16.04 安装php 5 6等版本

    //加入ppa $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update //安装5.6 $ sudo apt- //安装7 $ s ...

  6. SIM_AT_Command

    下面是GET请求 AT+HTTPPARA? 查询设置的Para命令 AT+SAPBR=1,1 (模块启动后设置一次即可)OK AT+HTTPINIT (初始化)OK AT+HTTPPARA=CONTE ...

  7. 高可用Kubernetes集群-6. 部署kube-apiserver

    八.部署kube-apiserver 接下来3章节是部署Kube-Master相关的服务,包含:kube-apiserver,kube-controller-manager,kube-schedule ...

  8. Python3实现机器学习经典算法(二)KNN实现简单OCR

    一.前言 1.ocr概述 OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗.亮的模式确定其形状,然 ...

  9. loadrunner--基础2

    LR11-03 一.并发测试(n VU) 1.并发测试两个条件 1)脚本中要有 集合点(并发点) 2)控制台中要设置并发策略(选择第一项,所有虚拟用户到达集合点后释放) 集合点: 5个线程,代表5个V ...

  10. 关于requestanimationframe

    首先字面理解,请求动画框架, 用法: var nextFrame = (function() { return window.requestAnimationFrame || window.webki ...