题意:

线段树是这样一种数据结构:根节点表示区间 [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. 20155325 2016-2017-2 《Java程序设计》第九周学习总结

    教材学习内容总结 SRP高内聚 开发工作原则:对扩充开发,对修改封闭.(对模块的行为可以扩充:模块的源代码不可更改) OO设计 依赖倒置原则:高层模块不依赖于 Linux视频笔记 安装时的说明(非ub ...

  2. spring boot启动报内存溢出的问题

    问题: springBoot项目,已经两次了,启动报内存溢出,内存泄露 分析: 内存泄露是因为垃圾回收器想要回收程序不用的对象,但是该对象还有引用存在 解决: 1.第一次是mybatis文件和Java ...

  3. 洛谷 P3369 【模板】普通平衡树(Treap/SBT)

    题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询x数的排名(排名定义为比当前数小的数的个数+1.若有多 ...

  4. Spring Cloud(一):服务治理技术概览【Finchley 版】

    Spring Cloud(一):服务治理技术概览[Finchley 版]  发表于 2018-04-14 |  更新于 2018-05-07 |  Spring Cloud Netflix 是 Spr ...

  5. Zabbix部署-LNMP环境

    原文发表于cu:2016-05-05 参考文档: LNMP安装:http://www.osyunwei.com/archives/7891.html 一.环境 Server:CentOS-7-x86_ ...

  6. AndroidArchitecture

    title: AndroidArchitecture date: 2016-04-08 23:26:20 tags: [architecture] categories: [Mobile,Androi ...

  7. 当Kubernets遇上阿里云 -之七层负载均衡(一).

    我们知道Kubernetes的service只能实现基于4层的负载均衡,无法提供7层之上的许多特性,诸如基于URL的负载均衡,SSL支持,三方授权等等:Ingress可以实现七层负载均衡的许多功能,唯 ...

  8. We are writing to let you know we have removed your selling privileges

     Hello, We are writing to let you know we have removed your selling privileges, canceled your listin ...

  9. 华为ensp使用

    网络学习目录 AR是() Auto:自动线 copper:双绞线缆  serial:串行线  pos: 光纤  E1:    ATM:    CTL:       STA:    PC:    MCS ...

  10. 用js两张图片合并成一张图片

    JS和canvas的合成方式 function drawAndShareImage(){ var canvas = document.createElement("canvas") ...