CF750G New Year and Binary Tree Paths(DP)
神仙题。为啥我第一眼看上去以为是个普及题
路径有两种,第一种是从 LCA 一边下去的,第二种是从 LCA 两边都下去了的。
先考虑第一种。
先枚举路径长度 \(h\)。
当 LCA 编号是 \(x\) 时,且所有儿子都是往左走时,和为 \((2^h-1)x\);所有儿子都往右走时,和为 \((2^h-1)x+2^h-1\)。显然 \((2^h-1)x\le s\le (2^h-1)x+2^h-1\)。
考虑从下往上第 \(i\) 个点从左儿子变成右儿子时(其它不变),总和会增加 \(2^i-1\)。
接下来我们发现无论这条路径长什么样,\(x\) 都等于 \(\lfloor\frac{s}{2^h-1}\rfloor\)。因为当 \(x\) 更小时,即使所有儿子都是往右走的,也没有 \(x\) 取 \(\lfloor\frac{s}{2^h-1}\rfloor\) 时所有儿子都往左走的和大,自然不可能和为 \(s\)。\(x\) 更大时同理。
所以我们想让总和再增加 \(s-(2^h-1)x\)。问题就是有多少种方案,从 \(2^1-1,2^2-1,\dots,2^{h-1}-1\) 中选出一些数(LCA 不能选),使得和为 \(s-(2^h-1)x\)。
这就简单了。枚举选了 \(cnt\) 个数,就是能否从 \(2^1,2^2,\dots,2^{h-1}\) 中选出一些数使得和为 \(s-(2^h-1)x+cnt\)。当且仅当 \(s-(2^h-1)x+cnt\) 中 \(1\) 的个数恰好为 \(cnt\) 方案为 \(1\),否则为 \(0\)。
接下来考虑第二种。
同样的,枚举左链和右链的长度 \(l\), \(r\)(都包括 LCA,至少我是这么写的)。同理可以推出 \(x\) 恒等于 \(\lfloor\frac{s-2^{r-1}+1}{2^l+2^r-3}\rfloor\)。
同理,考虑从全部是左儿子变成一些右儿子。(当然,LCA 的两个儿子除外)
问题就是有多少种方案,从 \(2^1-1,2^2-1,\dots,2^{l-1}-1,2^1-1,2^2-1,\dots,2^{r-1}-1\) 中选出一些数,使得和为 \(s-2^{r-1}+s-(2^l+2^r-3)x\)。
同样枚举个数 \(cnt\)。下文为了方便设 \(res=s-2^{r-1}+s-(2^l+2^r-3)x+cnt\)。
这回没办法了,老实上 DP。
令 \(f[i][j][k]\) 表示考虑 \(2^1\) 到 \(2^i\) 这些数,从中选出了 \(j\) 个,上一位有没有向这一位进位(\(k\) 是 01 变量)。
初始状态有 \(f[0][0][0]=1\)。要求是 \(f[\max(l,r)][cnt][0]\)。(由于选完之后不能再进位,所以 \(k=0\),此时 \(i=\max(l,r)\) 会更方便)
转移方程,枚举左子树选不选(设为 \(a\)),右子树选不选(设为 \(b\)),\(f[i+1][j+a+b][\lfloor\frac{k+a+b}{2}\rfloor]+=f[i][j][k]\)。
转移条件,首先对应的数要能选(即 \(i+1\ge l-1\) 时就选不了左子树了),另外 \(res\) 的第 \(i+1\) 位应恰好是 \((k+a+b)\bmod 2\)。
时间复杂度 \(O(\log^5s)\)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100010,mod=998244353;
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
int x=0,f=0;char ch=getchar();
while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
ll n,f[55][111][2];
int bitcnt(ll x){
int c=0;
for(;x;x&=x-1) c++;
return c;
}
ll solve1(){
ll ans=0;
FOR(i,1,50){
ll x=n/((1ll<<i)-1);
if(!x) break;
ll res=n-x*((1ll<<i)-1);
FOR(j,0,i-1) if((res+j)%2==0 && bitcnt(res+j)==j) ans++;
}
return ans;
}
ll solve2(){
ll ans=0;
FOR(l,2,50) FOR(r,2,50){
ll x=(n-(1ll<<(r-1))+1)/((1ll<<l)+(1ll<<r)-3);
if(!x) break;
// printf("x=%lld\n",x);
ll res=n-(1ll<<(r-1))+1-x*((1ll<<l)+(1ll<<r)-3);
FOR(cnt,0,l+r-4) if((res+cnt)%2==0){
// printf("l=%d,r=%d,cnt=%d,res+cnt=%d\n",l,r,cnt,res+cnt);
FOR(i,0,max(l,r)) FOR(j,0,min(cnt,2*i)) f[i][j][0]=f[i][j][1]=0;
f[0][0][0]=1;
FOR(i,1,max(l,r)) FOR(j,0,min(cnt,2*(i-1))){
FOR(k,0,1) FOR(a,0,1) FOR(b,0,1){
if(i>=l-1 && a==1) continue;
if(i>=r-1 && b==1) continue;
if((k+a+b)%2==((res+cnt)>>i)%2) f[i][j+a+b][(k+a+b)/2]+=f[i-1][j][k];
}
// printf("f[%d][%d][0]=%lld,f[%d][%d][1]=%lld\n",i-1,j,f[i-1][j][0],i-1,j,f[i-1][j][1]);
}
ans+=f[max(l,r)][cnt][0];
}
}
return ans;
}
int main(){
scanf("%lld",&n);
printf("%lld\n",solve1()+solve2());
}
CF750G New Year and Binary Tree Paths(DP)的更多相关文章
- LeetCode 257. Binary Tree Paths (二叉树路径)
Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...
- LeetCode OJ:Binary Tree Paths(二叉树路径)
Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...
- LeetCode 257. Binary Tree Paths(二叉树根到叶子的全部路径)
Given a binary tree, return all root-to-leaf paths. Note: A leaf is a node with no children. Example ...
- LeetCode Binary Tree Paths(简单题)
题意: 给出一个二叉树,输出根到所有叶子节点的路径. 思路: 直接DFS一次,只需要判断是否到达了叶子,是就收集答案. /** * Definition for a binary tree node. ...
- [CF750G] New Year and Binary Tree Paths
目录 简单的 组合的 题目链接 简单的 设从节点\(x\)开始不断往左儿子走h-1步,则编号和为\(x\sum_{i=0}^{h-1}2^i=x(2^h-1)\). 若倒数第\(i\)步走向的是右儿子 ...
- zoj 3965 Binary Tree Restoring(搜索)
Binary Tree Restoring Time Limit: 1 Second Memory Limit: 65536 KB Special Judge Given two ...
- Binary Tree Traversals(HDU1710)二叉树的简单应用
Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- LeetCode算法题-Binary Tree Paths(Java实现-3种解法)
这是悦乐书的第199次更新,第206篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第62题(顺位题号是257).给定二叉树,返回所有根到叶路径.例如: 输入: 1 / \ ...
- Palindromic Paths(DP)
描述 Given an N×N grid of fields (1≤N≤500), each labeled with a letter in the alphabet. For example: A ...
随机推荐
- ABAP分享五 ALV修改单元格并将修改数据更新到数据表中示例1
*下面的代码是在alv字段中修改字段的内容,点击保存后就可以保存数据至数据表. TABLES: spfli. DATA: wa_fieldcat TYPE lvc_s_fcat , " 相 ...
- Android框架式编程之Lifecycle
Lifecycle官方文档地址:https://developer.android.com/topic/libraries/architecture/lifecycle. 一.为什么要使用Lifecy ...
- Hibernate 数据层基类实现
提取经常操作表如新增.修改.删除.查询.分页查询.统计等业务功能,形成基类,用泛型传参,有利于每个实体对象数据层继承. package com.base.dao; import java.io.Ser ...
- 如何下载Twitter视频?最简单的保存推特视频的方法
Twitter上面的短视频越来越流行了,但是推特官方并没有提供下载通道.如果你想下载这些小视频到电脑或者手机(安卓/iPhone),该如何操作呢?下面介绍一种最简单的方法. 下载Twitter视频我们 ...
- 基于python的yaml配置文件使用方法
一.介绍 YAML是一种简洁的非标记语言 YAML以数据为中心,使用空白.缩进.分行组织数据,从而使表达更加简洁易懂 二.基本规则 大小写敏感 使用缩进表示层级关系 禁止使用Tab缩进,只能使用空格键 ...
- BootStrap 关于input与btn的点击focus取消特效相关css
取消btn按钮点击出现的外边框: .btn:focus, /*清除btn按钮点击出现的边框*/.btn:active:focus,.btn.active:focus,.btn.focus,.btn:a ...
- linux自建https证书
一.生成单向认证的https证书 建立服务器私钥,生成RSA秘钥. 会有两次要求输入密码, 然后获得了一个server.key文件. 以后使用此文件(通过openssl提供的命令或API)可能经常回要 ...
- MySQL数据以全量和增量方式,同步到ES搜索引擎
本文源码:GitHub·点这里 || GitEE·点这里 一.配置详解 场景描述:MySQL数据表以全量和增量的方式向ElasticSearch搜索引擎同步. 1.下载内容 elasticsearch ...
- .NET轻松实现支付宝服务窗网页授权并获取用户相关信息
前言: 最近在开发一个商业街区的聚合扫码支付功能,其中需要用到的有支付宝,微信两种支付方式,当然对于开发微信支付而已作为自己的老本行已经比较熟悉了,然而对于我来说支付宝支付还是头一次涉及到.这次项目中 ...
- 哈希算法原理【Java实现】(十)
前言 在入学时,学校为我们每位童鞋建立一个档案信息,当然每个档案信息都对应档案编号,还有比如在学校图书馆,图书馆为每本书都编了唯一的一个书籍号,那么问题来了,当我们需要通过档案号快速查到对应档案信息或 ...