「SCOI2014」方伯伯的商场之旅
「SCOI2014」方伯伯的商场之旅
题目描述
方伯伯有一天去参加一个商场举办的游戏。商场派了一些工作人员排成一行。每个人面前有几堆石子。说来也巧,位置在 \(i\) 的人面前的第 \(j\) 堆的石子的数量,刚好是 \(i\) 写成 \(K\) 进制后的第 \(j\) 位。
现在方伯伯要玩一个游戏,商场会给方伯伯两个整数 \(L,R\)。方伯伯要把位置在 \([L, R]\) 中的每个人的石子都合并成一堆石子。每次操作,他可以选择一个人面前的两堆石子,将其中的一堆中的某些石子移动到另一堆,代价是移动的石子数量\(\times\)移动的距离。商场承诺,方伯伯只要完成任务,就给他一些椰子,代价越小,给他的椰子越多。所以方伯伯很着急,想请你告诉他最少的代价是多少。
\(1≤L≤R≤10^{15}, 2≤K≤20\)。
解题思路 :
首先考虑一下对于某一个数如何求出其合并成一堆的代价,观察发现,最终答案的形态一定可以转化成所有数位都移到某一位
那么问题就转化为找出一个数位,使得其他数位移动到它的总代价最小,可以直接带权中位数求解
但实际上,带权中位数在数位 \(dp\) 的过程中状态不好表示,不妨再多考虑一下子问题解法的由来
考虑一下带权中位数 \(p\) ,其必然满足 \(val_p + \sum_{i=1}^{p-1} val_i \geq \sum_{i=p+1}^{n}\) ,反之同理,也就说,其无论往左移动或者往右移动都不会更优了
我们不妨先假设初始的 \(p = 1\) ,那么就只需要考虑 \(p\) 往右移动到 \(p+1\) 新增的代价了,显然是 \(\sum_{i=1}^{p} val_i - \sum_{i=p+1}^{n} val_i\)
此时如果代价 \(< 0\) 那么说明往右移动会更优,当某一时刻代价 \(\geq 0\) 的时候说明 \(p\) 既不能往右移动也不能往左移动了,此时其是带权中位数
也就是说,我们可以让所有数先移动到 \(1\) ,然后算出每一个 \(p\) 向右移动到 \(p+1\) 的代价,然后把所有 \(<0\) 的代价加上即可
具体实现的话就是一个比较简单的数位 \(dp\) ,考虑分两步计算:
\(f[i][0/1]\) 表示前 \(i\) 个数位,之前是否是上界的前缀的数全部移到第一位的总代价,枚举数位转移即可
对于每一个 \(p\in[1,len]\) ,算出 \(g[i][sum][0/1]\) 表示前 \(i\) 个数位,满足 \(\sum_{i=1}^{p} val_i - \sum_{i=p+1}^{n} val_i = sum\) 的数的个数,也是简单的枚举数位转移即可
注意在前导 \(0\) 的处理上,前导 \(0\) 不能被计算到距离里面,可以考虑每次只做恰好等于 \(n\) 位的数,多拿几个上界做几次,也可以加细节判掉,总复杂度是 \(O(log^3nK)\)
/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
#define int ll
const int zzd = 401;
int f[25][2], ss[25][2], g[25][1005][2], s[25], tmp[25], L, R, bs, lim, ans, ans2;
inline int Getcost(){
int res = 0; memset(f, 0, sizeof(f)), memset(ss, 0, sizeof(ss));
f[1][0] = s[1] - 1, f[1][1] = 1;
for(int i = 2; i <= lim; i++){
for(int j = 0; j < bs; j++){
f[i][0] += f[i-1][0];
ss[i][0] += ss[i-1][0] + f[i-1][0] * (i - 1) * j;
}
for(int j = 0; j < s[i]; j++){
f[i][0] += f[i-1][1];
ss[i][0] += ss[i-1][1] + f[i-1][1] * (i - 1) * j;
}
f[i][1] += f[i-1][1];
ss[i][1] += ss[i-1][1] + f[i-1][1] * s[i] * (i - 1);
}
res += ss[lim][0] + ss[lim][1];
return res;
}
inline int solve(int num){
lim = 0; while(num) tmp[++lim] = num % bs, num /= bs;
for(int i = 1; i <= lim; i++) s[i] = tmp[lim-i+1];
int cost = Getcost();
for(int p = 1; p <= lim; p++){
memset(g, 0, sizeof(g)), g[1][zzd-s[1]][1] = 1;
for(int i = 1; i < s[1]; i++) g[1][zzd-i][0] = 1;
for(int i = 2; i <= lim; i++)
for(int j = -400; j <= 400; j++){
int sgn = i <= p ? 1 : -1;
for(int k = 0; k < bs; k++) g[i][j+zzd][0] += g[i-1][j+sgn*k+zzd][0];
for(int k = 0; k < s[i]; k++) g[i][j+zzd][0] += g[i-1][j+sgn*k+zzd][1];
g[i][j+zzd][1] += g[i-1][j+sgn*s[i]+zzd][1];
}
for(int j = 1; j <= 400; j++) cost -= (g[lim][j+zzd][0] + g[lim][j+zzd][1]) * j;
}
return cost;
}
inline int calc(int x){
int num = x, n = 0, ans = 0;
while(num) ++n, num /= bs;
ans += solve(x); int base = 0;
for(int i = 1; i < n; i++)
base = base * bs + bs - 1, ans += solve(base);
return ans;
}
signed main(){
read(L), read(R), read(bs);
cout << calc(R) - calc(L - 1);
return 0;
}
「SCOI2014」方伯伯的商场之旅的更多相关文章
- 「SCOI2014」方伯伯的商场之旅 解题报告
「SCOI2014」方伯伯的商场之旅 我一开始的想法会被两个相同的集合位置去重给搞死,不过应该还是可以写的,讨论起来老麻烦. 可以先钦定在\(1\)号点集合,然后往后调整一部分. 具体一点,通过前缀和 ...
- 「SCOI2014」方伯伯运椰子 解题报告
「SCOI2014」方伯伯运椰子 可以看出是分数规划 然后我们可以看出其实只需要改变1的流量就可以了,因为每次改变要保证流量守恒,必须流成一个环,在正负性确定的情况下,变几次是无所谓的. 然后按照套路 ...
- 「SCOI2014」方伯伯的 OJ 解题报告
「SCOI2014」方伯伯的 OJ 和列队有点像,平衡树点分裂维护即可 但是需要额外用个set之类的对编号查找点的位置 插入完了后记得splay,删除时注意特判好多东西 Code: #include ...
- 「SCOI2014」方伯伯的玉米田 解题报告
#2211. 「SCOI2014」方伯伯的玉米田 发现是取一个最长不下降子序列 我们一定可以把一个区间加的右端点放在取出的子序列的最右边,然后就可以dp了 \(dp_{i,j}\)代表前\(i\)个玉 ...
- [BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)
3598: [Scoi2014]方伯伯的商场之旅 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 449 Solved: 254[Submit][Sta ...
- 洛谷P3286 [SCOI2014]方伯伯的商场之旅
题目:洛谷P3286 [SCOI2014]方伯伯的商场之旅 思路 数位DP dalao说这是数位dp水题,果然是我太菜了... 自己是不可能想出来的.这道题在讲课时作为例题,大概听懂了思路,简单复述一 ...
- 【bzoj3598】: [Scoi2014]方伯伯的商场之旅
Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...
- [SCOI2014]方伯伯的商场之旅
Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...
- 【数位DP】SCOI2014 方伯伯的商场之旅
题目内容 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子. 说来也巧,位置在 \(i\) 的人面前的第 \(j\) 堆的石子的数量,刚好是 \(i\) 写成 ...
随机推荐
- Lua的工具资源3
[LuaSrcDiet] (5.0.2) - 通过删除不必要的空白和注释缩减Lua文件的大小. [LuaProfiler] (5.0) - 一个用来查找Lua应用瓶颈的工具time profiler ...
- 【leetcode 简单】第三十一题 买卖股票的最佳时机
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股票. 示例 ...
- wordpress 模板制作之一
WP模板工作原理图:
- Attention is all you need 论文详解(转)
一.背景 自从Attention机制在提出之后,加入Attention的Seq2Seq模型在各个任务上都有了提升,所以现在的seq2seq模型指的都是结合rnn和attention的模型.传统的基于R ...
- Lucene7.2.1系列(三)查询及高亮
系列文章: Lucene系列(一)快速入门 Lucene系列(二)luke使用及索引文档的基本操作 Lucene系列(三)查询及高亮 一 准备 创建项目并添加Maven依赖 <dependenc ...
- flask插件系列之SQLAlchemy实用技巧
下面记录一下SQLAlchemy使用的技巧. 在多模块下定义models 如果由多个蓝图下读定义了model模块,在初始化的时候需要加载到上下文中. 当使用flask_Migrate迁移数据库的时候, ...
- 不老的神器:安全扫描器Nmap渗透使用指南【转】
介绍 nmap是用来探测计算机网络上的主机和服务的一种安全扫描器.为了绘制网络拓扑图Nmap的发送特制的数据包到目标主机然后对返回数据包进行分析.Nmap是一款枚举和测试网络的强大工具. 特点 主机探 ...
- [ python ] 初始面向对象
首先,通过之前学习的函数编写一个 人狗大战 的例子. 分析下这个需求,人 狗 大战 三个事情.角色:人.狗动作:狗咬人,人打狗 先创建人和狗两个角色: def person(name, hp, ag ...
- sshd_config OpenSSH SSH 进程配置文件配置说明
名称 sshd_config – OpenSSH SSH 服务器守护进程配置文件 大纲 /etc/ssh/sshd_config 描述sshd 默认从 /etc/ssh/sshd_config 文件( ...
- LeetCode765. Couples Holding Hands
N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...