zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    day25:接口类和抽象类
    vue1
    How the weather influences your mood?
    机器学习实验方法与原理
    How human activities damage the environment
    Slow food
    Brief Introduction to Esports
    Massive open online course (MOOC)
    Online learning in higher education
    Tensorflow Dataset API
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5318360.html
Copyright © 2011-2022 走看看