分析

首先,请允许我 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的更多相关文章

  1. luogu P5342 [TJOI2019]甲苯先生的线段树

    传送门 你个好好的省选怎么可以出CF原题啊,你们这个题害人不浅啊,这样子出题像极了cxk,说到cxk,我又想起了他是NBA形象大使,跟我是西游文化大使一样一样的,今年下半年... 别说了,jinsai ...

  2. [TJOI2019] 甲苯先生的线段树

    臭名昭著的巧合:CF750G 题意:在无限深度的一颗线段树中询问编号和为S的简单路径条数. 题解传送门 这道题相当于在原来基础上多了询问两点间简单路径的编号的的问题. 直觉告诉我们只需要求出两点在线段 ...

  3. p5342 [TJOI2019]甲苯先生的线段树

    分析  代码 #include<bits/stdc++.h> using namespace std; #define int long long ],yy[],cnt1,cnt2; ][ ...

  4. 【题解】Luogu P5342 [TJOI2019]甲苯先生的线段树

    原题传送门 挺有趣的一道题 \(c=1\),暴力求出点权和n即可 \(c=2\),先像\(c=1\)一样暴力求出点权和n,考虑有多少路径点权和也为n 考虑设x为路径的转折点,\(L\)为\(x\)向左 ...

  5. 【LOJ】#3109. 「TJOI2019」甲苯先生的线段树

    LOJ#3109. 「TJOI2019」甲苯先生的线段树 发现如果枚举路径两边的长度的话,如果根节点的值是$x$,左边走了$l$,右边走了$r$ 肯定答案会是$(2^{l + 1} + 2^{r + ...

  6. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  7. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  8. lightoj1085 线段树+dp

    //Accepted 7552 KB 844 ms //dp[i]=sum(dp[j])+1 j<i && a[j]<a[i] //可以用线段树求所用小于a[i]的dp[j ...

  9. [CF 474E] Pillars (线段树+dp)

    题目链接:http://codeforces.com/contest/474/problem/F 意思是给你两个数n和d,下面给你n座山的高度. 一个人任意选择一座山作为起始点,向右跳,但是只能跳到高 ...

随机推荐

  1. NOIP 2017 逛公园 题解

    题面 这道题是一道不错的计数类DP: 首先我们一定要跑一遍dijkstra来求得每个点到1号点的最短路: 注意题干,题中并没有说所有点都可以到达n好点,只说了存在一条1号点到n号点的路径:所以我们在反 ...

  2. c++学习之对象和类——构造函数和析构函数

    再认真理一遍~ 0.类 这里先来定义一个类,便于后面的理解.参考C++ Primer Plus class Stock { private: std::string company; long sha ...

  3. git clone 含有子模块的项目

    当一个 git 项目包含子模块(submodule) 时,直接克隆下来的子模块目录里面是空的. 有两种方法解决: 方法一 如果项目已经克隆到了本地,执行下面的步骤: 初始化本地子模块配置文件 git ...

  4. sklearn-GDBT

    GDBT 可以解决分类和回归问题 回归问题 def __init__(self, loss='ls', learning_rate=0.1, n_estimators=100, subsample=1 ...

  5. copy小练习

    # 1. # 有如下 # v1 = {'郭宝元', '李杰', '太白', '梦鸽'} # v2 = {'李杰', '景女神} # 请得到 v1 和 v2 的交集并输出 # 请得到 v1 和 v2 的 ...

  6. Elasticsearch6.2集群搭建, centos7

    原文地址,转载请注明出处:https://blog.csdn.net/qq_34021712/article/details/79330028   ©王赛超 环境介绍 服务器 是否可以成为主节点 是否 ...

  7. sql server delete语句

    delete语句 --DELETE 语句用于删除表中的行 语法:delete from 表名称 where 列名称 = 值 --可以在不删除表的情况下删除所有的行.这意味着表的结构.属性和索引都是完整 ...

  8. 使用@ResponseBody输出JSON

    添加jackson依赖 添加@ResponseBody 测试: 原理: 当一个处理请求的方法标记为@ResponseBody时,就说明该方法需要输出其他视图(json.xml),SpringMVC通过 ...

  9. Arduino控制LED灯(开关控制)

    问题:当使用"digitalRead(BUT) == 1"控制LED灯时会出现"digitalWrite(LED, ledState);"的值出现跳动. 原因: ...

  10. multipart/form-data请求与文件上传的细节

    <!DOCTYPE html><html><head lang="en">  <meta charset="UTF-8" ...