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

发现如果枚举路径两边的长度的话,如果根节点的值是\(x\),左边走了\(l\),右边走了\(r\)

肯定答案会是\((2^{l + 1} + 2^{r + 1} - 3)x + t\),可以发现\(t < (2^{l + 1} + 2^{r + 1} - 3)\),于是考虑计算对于\(t\),左边走了\(l\),右边走了深度\(r\),几种走法使得总和为\(t\)

容易发现右边最小一定是走了\(2^{r} - 1\)于是可以扣掉

再发现我们其实是对于左边和右边串选择长度为\([1,l - 1]\)和\([1,r - 1]\)的11111111......

但是这种\(i\)个1的形式不太好dp,于是就转化成\(2^{i + 1} - 1\)的形式,每次强制选择的个数,只要考虑\(2^{i+ 1}\)去dp就好了,\(t\)加上强制选的个数再进行数位dp就可以了

复杂度是\(d^{5}\)的,有点慢,但是可以过,因为上界很远。。。

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int d,c;int64 a,b,s;
int getpos(int64 x) {
int res = 0;
while(x) {
++res;
x >>= 1;
}
return res;
}
int64 GetSum(int64 a,int64 b) {
int ta = getpos(a),tb = getpos(b);
if(ta > tb) {swap(a,b);swap(ta,tb);}
int64 res = 0;
for(int i = 1 ; i <= tb - ta ; ++i) {res += b;b >>= 1;}
while(a != b) {
res += a;res += b;
a >>= 1;b >>= 1;
}
res += a;
return res;
}
map<int64,int64> zz;
int La,Lb;
int64 dp[55][105][2];
int64 Process(int64 s,int num) {
memset(dp,0,sizeof(dp));
dp[0][0][0] = 1;
if(s & 1) return 0;
for(int i = 1 ; i <= 50 ; ++i) {
int to = (s >> i) & 1;
for(int j = 0 ; j <= num ; ++j) {
for(int t = 0 ; t <= 1 ; ++t) {
int up = (i <= La) + (i <= Lb);
for(int h = 0 ; h <= up ; ++h) {
if(((t + h) & 1) == to) {
int64 f = 1;
if(h == 1 && up == 2) f = 2;
dp[i][j + h][(t + h - to) / 2] += f * dp[i - 1][j][t];
}
}
}
}
}
return dp[50][num][0];
}
int64 Calc() {
int64 res = 0;
for(int i = 0 ; i <= d ; ++i) {
for(int j = 0 ; j <= d ; ++j) {
int64 k = (1LL << i + 1) + (1LL << j + 1) - 3;
int64 tmp = s;
if(tmp < k) continue;
if(getpos(tmp / k) + max(i,j) > d) continue;
tmp = tmp % k;
if(tmp < (1LL << j) - 1) continue;
tmp -= (1LL << j) - 1;
if(tmp == 0) {++res;continue;}
La = i - 1,Lb = j - 1;
for(int h = 0 ; h <= max(i - 1,0) + max(j - 1,0) ; ++h) {
res += Process(tmp + h,h);
}
}
}
return res;
}
void Solve() {
read(d);read(a);read(b);read(c);
s = GetSum(a,b);
if(c == 1) {out(s);enter;}
else {out(Calc() - 1);enter;}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
int T;
read(T);
for(int i = 1 ; i <= T ; ++i) {
Solve();
}
return 0;
}

(权游文化还行。。。最近刚开始追权游23333感觉题面非常有趣)

【LOJ】#3109. 「TJOI2019」甲苯先生的线段树的更多相关文章

  1. LOJ 2302 「NOI2017」整数——压位线段树

    题目:https://loj.ac/problem/2302 压30位,a最多落在两个位置上,拆成两次操作. 该位置加了 a 之后,如果要进位或者借位,查询一下连续一段 0 / 1 ,修改掉,再在含有 ...

  2. LOJ#3104「TJOI2019」甲苯先生的字符串

    题目描述 一天小甲苯得到了一条神的指示,他要把神的指示写下来,但是又不能泄露天机,所以他要用一种方法把神的指示记下来. 神的指示是一个字符串,记为字符串 \(s_1\),\(s_1\) 仅包含小写字母 ...

  3. loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)

    题意 题目链接 Sol 线性基+线段树分治板子题.. 调起来有点自闭.. #include<bits/stdc++.h> #define fi first #define se secon ...

  4. LG5337/BZOJ5508 「TJOI2019」甲苯先生的字符串 线性动态规划+矩阵加速

    问题描述 LG5337 BZOJ5508 题解 设\(opt_{i,j}(i \in [1,n],j \in [1,26])\)代表区间\([1,i]\),结尾为\(j\)的写法. 设\(exist_ ...

  5. LG5338/BZOJ5509/LOJ3105 「TJOI2019」甲苯先生的滚榜 Treap

    问题描述 LG5338 LOJ3105 BZOJ5509 题解 建立一棵\(\mathrm{Treap}\),把原来的\(val\)换成两个值\(ac,tim\) 原来的比较\(val_a<va ...

  6. 「TJOI2019」甲苯先生的滚榜

    题目链接 问题分析 参照数据范围,我们需要一个能够在\(O(n\log n)\)复杂度内维护有序数列的数据结构.那么平衡树是很好的选择.参考程序中使用带旋Treap. 参考程序 #pragma GCC ...

  7. LOJ 3055 「HNOI2019」JOJO—— kmp自动机+主席树

    题目:https://loj.ac/problem/3055 先写了暴力.本来想的是 n<=300 的那个在树上暴力维护好整个字符串, x=1 的那个用主席树维护好字符串和 nxt 数组.但 x ...

  8. LOJ 2339 「WC2018」通道——边分治+虚树

    题目:https://loj.ac/problem/2339 两棵树的话,可以用 CTSC2018 暴力写挂的方法,边分治+虚树.O(nlogn). 考虑怎么在这个方法上再加一棵树.发现很难弄. 看了 ...

  9. 2018.06.26「TJOI2018」数学计算(线段树)

    描述 小豆现在有一个数 xxx ,初始值为 111 . 小豆有 QQQ 次操作,操作有两种类型: 111 $ m$ : x=x×mx=x×mx=x×m ,输出 xxx modmodmod MMM : ...

随机推荐

  1. 漫谈计算机编码:从ASCII码到UTF-8

    第一阶段 盘古开天辟地——ASCII码 计算机大家都知道,本质是二进制运算和存储.在计算机中人类的几乎所有文字和字符都没法直接表示,所以美国人在发明计算机的时候为了让计算机可以用于保存和传输文字,就发 ...

  2. python 二维数组 转 矩阵

    x = numpy.array([[,,],[,,],[,,]]) print x print x.shape 输出 [[ ] [ ] [ ]] (3L, 3L) [Finished .2s]

  3. 【平台中间件】为什么用etcd而不用ZooKeeper?从应用场景到实现原理的全方位解读

    前言 博主在工作过程中经常接触到ETCD,搜索相关资料的时候发现排名最高的是一篇图片全是404的转载文章,后来看到了原文,感觉有义务让更多的人看到这样的精品文章,所以进行了转载. 原文发布在infoQ ...

  4. 后盾网lavarel视频项目---Vue项目使用vue-awesome-swiper轮播插件

    后盾网lavarel视频项目---Vue项目使用vue-awesome-swiper轮播插件 一.总结 一句话总结: vue中的插件的使用和js插件的使用一样的简单,只是vue插件的引入过程有些不同 ...

  5. WPF global exception handler

    WPF global exception handler [duplicate] https://stackoverflow.com/questions/1472498/wpf-global-exce ...

  6. centos 下 安装vim

    我们在安装完Centos后,它默认的是安装了VI编辑器,VIM是没有安装的,所以我们在使用vim test.txt时会提示: vim command not found ... 这就是说明我们的Lin ...

  7. 实时更新DataGridView 合计值

    public partial class Form1 : Form { public Form1() { InitializeComponent(); dataGridView1.DataSource ...

  8. springmvc快速入门(XML版本)

    1)springmvc快速入门(传统版) 步一:创建springmvc-day01这么一个web应用 步二:导入springioc,springweb , springmvc相关的jar包 步三:在/ ...

  9. ShockUtil振动工具类

    import android.app.Activity; import android.app.Service; import android.content.Context; import andr ...

  10. Android启动页面的正确打开方式 (转载)

    最近由于领导要求写一个手机APP,于是自学开始,不经意间想到使用过的手机APP在打开的时候都是会有一个启动页面,这是如何实现的呢?比较好奇,于是在网上搜到了以下这篇文章,经过个人实验的确可行,不过原文 ...