bzoj5123 [Lydsy12月赛]线段树的匹配
题意:
线段树是这样一种数据结构:根节点表示区间 [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月赛]线段树的匹配的更多相关文章
- 【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索
题目描述 求一棵 $[1,n]$ 的线段树的最大匹配数目与方案数. $n\le 10^{18}$ 题解 树形dp+记忆化搜索 设 $f[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配选择根 ...
- bzoj 5123: [Lydsy1712月赛]线段树的匹配
设f[0/1][x]为区间[1,x]的根向下 不选(0)或者选(1) 的dp pair<最优值,方案数>. 可以很容易的发现总状态数就是log级别的,因为2*n 与 (2*n+1 或者 ...
- BZOJ5123 线段树的匹配(树形dp)
线段树的任意一棵子树都相当于节点数与该子树相同的线段树.于是假装在树形dp即可,记忆化搜索实现,有效状态数是logn级别的. #include<iostream> #include< ...
- CF308C-Sereja and Brackets-(线段树+括号匹配)
题意:给出一段括号,多次询问某个区间内能匹配多少括号. 题解:线段树,结构体三个属性,多余的左括号l,多余的右括号r,能够匹配的括号数val. 当前结点的val=左儿子的val+右儿子的val+min ...
- bzoj千题计划164:bzoj5123: 线段树的匹配
http://www.lydsy.com/JudgeOnline/upload/201712/prob12.pdf dp[len][0/1] 表示节点表示区间长度为len,节点选/不选的 最大匹配 s ...
- 【BZOJ3413】匹配(后缀自动机,线段树合并)
[BZOJ3413]匹配(后缀自动机,线段树合并) 题面 BZOJ 题解 很好的一道题目. 做一个转化,匹配的次数显然就是在可以匹配的区间中,每个前缀的出现次数之和. 首先是空前缀的出现次数,意味着你 ...
- 【BZOJ4919】[Lydsy六月月赛]大根堆 线段树合并
[BZOJ4919][Lydsy六月月赛]大根堆 Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切 ...
- 牛客网 牛客小白月赛5 I.区间 (interval)-线段树 or 差分数组?
牛客小白月赛5 I.区间 (interval) 休闲的时候写的,但是写的心情有点挫,都是完全版线段树,我的一个队友直接就水过去了,为啥我的就超内存呢??? 试了一晚上,找出来了,多初始化了add标记数 ...
- [Bzoj5358][Lydsy1805月赛]口算训练(预处理+动态开点线段树)
5358: [Lydsy1805月赛]口算训练 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 318 Solved: 105[Submit][Stat ...
随机推荐
- 20155330 实验三 敏捷开发与XP实践
20155330 实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验步骤 (一)敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法应用到软件的开发.运营和维护上的过程. ...
- MySQL优化Explain命令简介(二)
type列 MySQL手册上注明type列用于描述join type,不过我们认为把这一列视为对access type--即MySQL决定如何在表中寻找数据的方式的描述,更加合适一些,以下所示从最坏情 ...
- 【HDU3117】Fibonacci Numbers
[HDU3117]Fibonacci Numbers 题面 求斐波那契数列的第\(n\)项的前四位及后四位. 其中\(0\leq n<2^{32}\) 题解 前置知识:线性常系数齐次递推 其实后 ...
- 自己用C语言写RL78 serial bootloader
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 之前用C实现过多款PI ...
- NB-IOT模组指令AT+NMSTATUS和AT+CGPADDR对比
1. AT+NMSTATUS,这个指令是用来查询模块在IOT平台的注册情况.注册指的是lwm2m协议里面的注册机制,详细可以参考lwm2m协议. 2. AT+MREGSWT,设置重启之后,自动启动注册 ...
- [bzoj1500][luogu2042][cogs339][codevs1758]维修数列(维护数列)
先给自己立一个flag 我希望上午能写完 再立一个flag 我希望下午能写完. 再立一个flag 我希望晚上能写完... 我终于A了... 6700+ms...(6728) 我成功地立了3个flag. ...
- 使用Xamarin实现串口通讯
前几天我写了年度总结,然后有人说让我教一下他Xamarin串口通讯怎么做,其实跟java没有多大区别. 记得我刚开始接到公司这个项目的时候很懵逼,我去看了别的安卓串口工具,都不行我当时是RS232串口 ...
- python购物车优化
一.需求分析 拥有用户接口和商家接口 用户能够进行消费记录查询,充值,购物等功能,消费记录存储于数据库 商家可以进行商品的增删改等操作 二.程序流程图 程序大致流程图如下: 三.代码实现 本程序分成两 ...
- Visual Assist 试用期过期怎么办?
Visual Assist 试用期过期怎么办 VS这个强大的编译器常常会配置番茄小助手 Visual Assist,但是有时候试用期会过期,又想免费试用,怎么办呢? 有一个方法可以充值番茄助手的试用期 ...
- tendermint 跟tikv结合
import ( "fmt" "github.com/allegro/bigcache" "github.com/kooksee/usmint/cmn ...