[LOJ3109][TJOI2019]甲苯先生的线段树:DP
分析
首先,请允许我 orz HN队长zsy。链接
我们发现树上的链有两种类,一类是直上直下的,一类不是直上直下的(废话)。并且,如果我们确定了左侧和右侧的链的长度和整条链上所有节点的编号之和,那么这个链的深度最浅的的节点的编号也是可以唯一地确定的。(也有可能不存在这样的节点,判掉就好)
以第二类链为例,我们可以枚举左侧链和右侧链的长度,令深度最浅的节点的编号为\(x\),那么我们发现这条链的编号之和的下界可以写成\(kx+b\)的形式。于是我们可以求出\(x=\lfloor\frac{sum-b}{k}\rfloor\),然后类似数位DP那样决策左侧链和右侧链的每个位置分别向左儿子还是右儿子走就好了,这个过程可以通过记忆化搜索实现。
时间复杂度不会算。
代码
#include <bits/stdc++.h>
#define rin(i,a,b) for(int i=(a);i<=(b);++i)
#define irin(i,a,b) for(int i=(a);i>=(b);--i)
#define trav(i,a) for(int i=head[a];i;i=e[i].nxt)
#define Size(a) (int)a.size()
#define pb push_back
#define mkpr std::make_pair
#define fi first
#define se second
#define lowbit(a) ((a)&(-(a)))
typedef long long LL;
using std::cerr;
using std::endl;
inline LL read(){
LL x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int d,c;
LL a,b,n;
std::map<LL,LL> mp1[55],mp2[55][55];
inline LL solve1(LL x,LL y){
LL ret=0;
while(x!=y){
if(x<y)std::swap(x,y);
ret+=x;x>>=1;
}
ret+=x;
return ret;
}
LL dfs1(int x,LL w){
if(w<0)return 0;
if(w>(1ll<<(x+1))-2-x)return 0;
if(!x)return w==0;
if(mp1[x].find(w)!=mp1[x].end())return mp1[x][w];
return mp1[x][w]=dfs1(x-1,w)+dfs1(x-1,w-(1ll<<x)+1);
}
LL dfs2(int l,int r,LL w){
if(l>r)std::swap(l,r);
if(w<0)return 0;
if(w>(1ll<<(l+1))+(1ll<<(r+1))-4-l-r)return 0;
if(!r)return w==0;
if(mp2[l][r].find(w)!=mp2[l][r].end())return mp2[l][r][w];
return mp2[l][r][w]=dfs2(l,r-1,w)+dfs2(l,r-1,w-(1ll<<r)+1);
}
int main(){
int T=read();
while(T--){
d=read(),a=read(),b=read(),c=read(),n=(1<<d)-1;
LL len=solve1(a,b);
if(c==1){printf("%lld\n",len);continue;}
LL ans=0;
rin(i,0,d-1){
LL k=(1ll<<(i+1))-1,x=len/k;
if(k<=len&&(int)log2((long double)x)+1+i<=d){
ans+=dfs1(i,len%k);
}
}
rin(l,1,d-1)rin(r,1,d-1){
LL k=(1ll<<(l+1))+(1ll<<(r+1))-3,b=(1ll<<r)-1,x=(len-b)/k;
if(k+b<=len&&(int)log2((long double)x)+1+std::max(l,r)<=d){
ans+=dfs2(l-1,r-1,(len-b)%k);
}
}
printf("%lld\n",ans-1);
}
return 0;
}
[LOJ3109][TJOI2019]甲苯先生的线段树:DP的更多相关文章
- luogu P5342 [TJOI2019]甲苯先生的线段树
传送门 你个好好的省选怎么可以出CF原题啊,你们这个题害人不浅啊,这样子出题像极了cxk,说到cxk,我又想起了他是NBA形象大使,跟我是西游文化大使一样一样的,今年下半年... 别说了,jinsai ...
- [TJOI2019] 甲苯先生的线段树
臭名昭著的巧合:CF750G 题意:在无限深度的一颗线段树中询问编号和为S的简单路径条数. 题解传送门 这道题相当于在原来基础上多了询问两点间简单路径的编号的的问题. 直觉告诉我们只需要求出两点在线段 ...
- p5342 [TJOI2019]甲苯先生的线段树
分析 代码 #include<bits/stdc++.h> using namespace std; #define int long long ],yy[],cnt1,cnt2; ][ ...
- 【题解】Luogu P5342 [TJOI2019]甲苯先生的线段树
原题传送门 挺有趣的一道题 \(c=1\),暴力求出点权和n即可 \(c=2\),先像\(c=1\)一样暴力求出点权和n,考虑有多少路径点权和也为n 考虑设x为路径的转折点,\(L\)为\(x\)向左 ...
- 【LOJ】#3109. 「TJOI2019」甲苯先生的线段树
LOJ#3109. 「TJOI2019」甲苯先生的线段树 发现如果枚举路径两边的长度的话,如果根节点的值是$x$,左边走了$l$,右边走了$r$ 肯定答案会是$(2^{l + 1} + 2^{r + ...
- Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)
[题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- lightoj1085 线段树+dp
//Accepted 7552 KB 844 ms //dp[i]=sum(dp[j])+1 j<i && a[j]<a[i] //可以用线段树求所用小于a[i]的dp[j ...
- [CF 474E] Pillars (线段树+dp)
题目链接:http://codeforces.com/contest/474/problem/F 意思是给你两个数n和d,下面给你n座山的高度. 一个人任意选择一座山作为起始点,向右跳,但是只能跳到高 ...
随机推荐
- 如何决定使用 HashMap 还是 TreeMap? (转)
问:如何决定使用 HashMap 还是 TreeMap? 介绍 TreeMap<K,V>的Key值是要求实现java.lang.Comparable,所以迭代的时候TreeMap默认是按照 ...
- CSS3鼠标滑过图片3D旋转动画
在线演示 本地下载
- CentOS7 Python3安装redis
CentOS7安装配置Redis 第一步:下载redis安装包 wget http://download.redis.io/releases/redis-4.0.9.tar.gz 想下载哪个版本可以复 ...
- PHP7 错误及异常机制
关键词 error 不能在编译期发现的运行期错误,比如试图用 echo 输出一个未赋值的变量,这类问题往往导致程序或逻辑无法继续下去而需要中断: exception 程序执行过程中出现意料之外的情况, ...
- LOJ题解#136. 最小瓶颈路 DFS+Kruskal
题目链接: https://loj.ac/problem/136 思路: 在我的这篇博客中已经讲到什么是最短瓶颈路,同时给出了一个用Kruskal求最短瓶颈路的一个简洁易懂的方法,然而这道题目可以看作 ...
- celery 分布式异步队列框架使用方法
简介: Celery 是一个python开发的异步分布式任务调度模块,是一个消息传输的中间件,可以理解为一个邮箱,每当应用程序调用celery的异步任务时,会向broker传递消息,然后celery ...
- 基于Zabbix 3.2.6版本的low-level-discover(lld)
个人使用理解: 1.使用一个返回值是JSON的KEY,在Templates或者Hosts中创建一个Discovery规则.该key的返回值类似于: 索引key -- value 类型 ...
- linux创建定时任务发送钉钉通知
一.现在钉钉里面添加机器人 添加成功后,复制出Webhook链接. 注意,自定义关键字时你的发送信息中一定要完整包含关键字 二.找到自己的服务器 1. sudo su 切换到root用户 2.cron ...
- 线程安全的Singleton要点
1.privat static Singleton 要加votatile关键字修饰,防止对象的初始化代码与引用赋值代码进行重排序. 2.getInstance方法,最外层要加if (instance ...
- 全自动链接克隆KVM虚拟机
virt-clone这个命令是基于全克隆的,也就是拷贝虚拟磁盘文件和虚拟配置文件来实现的完整克隆,速度慢,占用空间多 kvm软件包中并没有实现全自动链接克隆的命令或工具,只能手动实现,于是我决定写一个 ...