HDU 4362 Dragon Ball 线段树
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef __int64 ll;
const ll Inf = (ll)(1e15);
const int N = 1000 + 10;
const int M = 50 + 5;
struct node {
ll addv, min;
};
struct tnode {
int pos;
ll cos;
tnode() {
}
tnode(int _pos, ll _cos) {
pos = _pos;
cos = _cos;
}
}; node seg[N << 2];
vector<tnode> a[M];
int val[M][N][2];
ll d[M][N]; void Up(node& fa, node &ls, node& rs) {
if (ls.min > rs.min) {
fa.min = rs.min;
} else {
fa.min = ls.min;
}
}
void Down(node& fa, node& ls, node& rs) {
if (fa.addv != 0) {
ls.min += fa.addv;
rs.min += fa.addv;
ls.addv += fa.addv;
rs.addv += fa.addv;
fa.addv = 0;
}
}
void build(int i, int p, int l, int r, int rt) {
seg[rt].addv = 0;
if (l == r) {
seg[rt].min = d[i][l] + abs(p - a[i][l].pos);
} else {
int mid = (l + r) >> 1;
build(i, p, lson);
build(i, p, rson);
Up(seg[rt], seg[rt << 1], seg[rt << 1 | 1]);
}
}
void update(int L, int R, ll v, int l, int r, int rt) {
if (L <= l && r <= R) {
seg[rt].min += v;
seg[rt].addv += v;
} else {
int mid = (l + r) >> 1;
Down(seg[rt], seg[rt << 1], seg[rt << 1 | 1]);
if (L > mid)
update(L, R, v, rson);
else if (R <= mid)
update(L, R, v, lson);
else {
update(L, mid, v, lson);
update(mid + 1, R, v, rson);
}
Up(seg[rt], seg[rt << 1], seg[rt << 1 | 1]);
}
}
void update_pos(int i, int j, int from, int to, int l, int r, int rt) {
if (l == r) {
int p = a[i][j].pos;
ll v = (ll)-abs(p - from) + abs(p - to);
seg[rt].min += v;
seg[rt].addv += v;
} else {
Down(seg[rt], seg[rt << 1], seg[rt << 1 | 1]);
int mid = (l + r) >> 1;
if (j <= mid)
update_pos(i, j, from, to, lson);
else
update_pos(i, j, from, to, rson);
Up(seg[rt], seg[rt << 1], seg[rt << 1 | 1]);
}
}
bool cc(const tnode& i, const tnode& j) {
return i.pos < j.pos;
}
void work() {
for (int i = 0; i < M; ++i)
a[i].clear(); int m, n, x, st, p, idx, idy;
scanf("%d%d%d", &n, &m, &st);
for (int i = 1; i <= n; ++i)
for (int j = 0; j < m; ++j)
scanf("%d", &val[i][j][0]);
for (int i = 1; i <= n; ++i)
for (int j = 0; j < m; ++j)
scanf("%d", &val[i][j][1]);
a[0].push_back(tnode(st, 0));
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < m; ++j)
a[i].push_back(tnode(val[i][j][0], val[i][j][1]));
sort(a[i].begin(), a[i].end(), cc);
}
// dp
for (int i = 0; i <= n; ++i)
for (int j = 0; j < a[i].size(); ++j)
d[i][j] = Inf;
d[0][0] = 0;
for (int i = 1; i <= n; ++i) {
p = a[i][0].pos;
build(i - 1, p, 0, a[i - 1].size() - 1, 1);
d[i][0] = a[i][0].cos + seg[1].min;
//
idx = -1;
while (idx + 1 < a[i - 1].size() && a[i - 1][idx + 1].pos < p)
++ idx;
idy = a[i - 1].size();
while (idy - 1 >= 0 && a[i - 1][idy - 1].pos > p)
-- idy;
//
for (int j = 1; j < a[i].size(); ++j) {
while (idy < a[i - 1].size() && a[i - 1][idy].pos <= a[i][j].pos)
++ idy;
if (idx >= 0)
update(0, idx, a[i][j].pos - p, 0, a[i - 1].size() - 1, 1);
if (idy < a[i - 1].size())
update(idy, a[i - 1].size() - 1, p - a[i][j].pos, 0, a[i - 1].size() - 1, 1);
//
for (int k = idx + 1; k < idy; ++k)
update_pos(i - 1, k, p, a[i][j].pos, 0, a[i - 1].size() - 1, 1);
//
d[i][j] = a[i][j].cos + seg[1].min;
p = a[i][j].pos;
while (idx + 1 < a[i - 1].size() && a[i - 1][idx + 1].pos < p)
++ idx;
}
}
ll ans = Inf;
for (int i = 0; i < a[n].size(); ++i)
ans = min(ans, d[n][i]);
cout << ans << endl;
}
int main() {
int cas;
scanf("%d", &cas);
while (cas -- > 0)
work();
return 0;
}
HDU 4362 Dragon Ball 线段树的更多相关文章
- HDU-3872 Dragon Ball 线段树+DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3872 题意:有n个龙珠按顺序放在一列,每个龙珠有一个type和一个权值,要求你把这n个龙珠分成k个段, ...
- HDU 4362 Dragon Ball 贪心DP
Dragon Ball Problem Description Sean has got a Treasure map which shows when and where the dragon ...
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- HDU 1556 Color the ball(线段树区间更新)
Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...
- hdu 1556 Color the ball (线段树+代码详解)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- hdu 1556 Color the ball(线段树区间维护+单点求值)
传送门:Color the ball Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/3276 ...
- hdu 1556 Color the ball 线段树
题目链接:HDU - 1556 N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气 ...
随机推荐
- Android ActionBar完全解析,使用官方推荐的最佳导航栏(上)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/18234477 本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工 ...
- Difference between enabled and userInteractionEnabled properties
I read through the documentation, and here are my findings. UIButton inherits from UIControl the boo ...
- easyUI的doCellTip 就是鼠标放到单元格上有个提示的功能
1:这个东西是我抄的(抄的哪儿的我就想不起来了- -)弹出的窗没有样式 不是很好看 //扩展 $.extend($.fn.datagrid.methods, { /** * 开打提示功能 * @pa ...
- 客户Oracle数据库在插入数据的时候报超出最大长度的错误(规避风险)
背景: 项目使用oracle数据,在开发环境测试一些正常.项目部署到客户的服务器上后,系统在添加数据的时候报错.输出错误信息,发现是“超出最大长度”的异常. 但是按照数据库的设计,添加的数据应该在允许 ...
- textField:shouldChangeCharactersInRange:replacementString:
http://blog.csdn.net/mamong/article/details/44964801
- hdu 1282 回文数猜想
Problem Description 一个正整数,如果从左向右读(称之为正序数)和从右向左读(称之为倒序数)是一样的,这样的数就叫回文数.任取一个正整数,如果不是回文数,将该数与他的倒序数相加,若其 ...
- 洛谷 P1066 2^k进制数
P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. ( ...
- MDX示例:求解中位数、四分位数(median、quartile)
一个人力资源咨询集团通过网络爬虫采集手段将多个知名招聘网站上发布的求职和招聘等信息准实时采集到自己的库里,形成一个数据量浩大的招聘信息库,跟踪全国招聘和求职的行业.工种.职位.待遇等信息,并通过商业智 ...
- Meta 整合
Meta 整合:http://segmentfault.com/a/1190000002407912
- 简单说pyglet.event
emitter,就是pyglet.event.EventDispatcher的子类, 负责发出事件的消息,并且规定了响应消息的函数名. class Consumer(pyglet.event.Even ...