9-3(线段树维护最大最小值)
2017-09-03 01:05
316 查看
HDU 5861 Road
There are n villages along a high way, and divided the high way into n-1 segments. Each segment would charge a certain amount of money for being open for one day, and you can open or close an arbitrary segment in an arbitrary day, but you can open or close the segment for just one time, because the workers would be angry if you told them to work multiple period.We know the transport plan in the next m days, each day there is one cargo need to transport from village aiai to village bibi, and you need to guarantee that the segments between aiai and bibi are open in the i-th day. Your boss wants to minimize the total cost of the next m days, and you need to tell him the charge for each day.
(At the beginning, all the segments are closed.)
Input
Multiple test case. For each test case, begins with two integers n, m(1<=n,m<=200000), next line contains n-1 integers. The i-th integer wiwi(1<=wiwi<=1000) indicates the charge for the segment between village i and village i+1 being open for one day. Next m lines, each line contains two integers ai,bi(1≤ai,bi<=n,ai!=bi)ai,bi(1≤ai,bi<=n,ai!=bi).Output
For each test case, output m lines, each line contains the charge for the i-th day.Sample Input
4 31 2 3
1 3
3 4
2 4
Sample Output
35
5
#include <bits/stdc++.h> using namespace std; int n, m; const int maxn = 200010; const int INF = 0x3f3f3f3f; int cost[maxn]; vector<int> vec_s[maxn], vec_t[maxn]; struct Tree{ int l, r, ddl; int open; }tree[maxn*5]; void build(int node){ tree[node].ddl = 0; tree[node].open = INF; if(tree[node].l == tree[node].r) return ; int mid = (tree[node].l + tree[node].r)/2; tree[node*2].l = tree[node].l; tree[node*2].r = mid; tree[node*2+1].l = mid+1; tree[node*2+1].r = tree[node].r; build(node*2); build(node*2+1); } void pushdown(int node){ tree[node*2].ddl = max(tree[node*2].ddl, tree[node].ddl); tree[node*2+1].ddl = max(tree[node*2+1].ddl, tree[node].ddl); tree[node*2].open = min(tree[node*2].open, tree[node].open); tree[node*2+1].open = min(tree[node*2+1].open, tree[node].open); } void update(int node, int s, int e, int c){ if(s <= tree[node].l && tree[node].r <= e){ if(tree[node].l != tree[node].r) pushdown(node); tree[node].ddl = max(tree[node].ddl, c); tree[node].open = min(tree[node].open, c); return; } pushdown(node); int mid = (tree[node].l + tree[node].r) / 2; if(s <= mid) update(node*2, s, e, c); if(e > mid) update(node*2+1, s, e, c); tree[node].open = max(tree[node*2].open, tree[node*2+1].open); tree[node].ddl = min(tree[node*2].ddl, tree[node*2+1].ddl); return; } void query(int node, int &tar, int& s, int& t){ if(tree[node].l == tree[node].r && tree[node].l == tar){ s = tree[node].open; t = tree[node].ddl; if(s == INF) s = t = 0; return; } pushdown(node); int mid = (tree[node].l + tree[node].r)/2; if(tar <= mid) query(node*2, tar, s, t); else query(node*2+1, tar, s, t); } int main() { while(cin >> n >> m){ for(int i = 1; i < n; i++){ scanf("%d", &cost[i]); } tree[1].l = 1, tree[1].r = n-1; build(1); for(int i = 1; i <= m; i++){ vec_s[i].clear(), vec_t[i].clear(); int s, e; scanf("%d%d", &s, &e); if(s>e) swap(s, e); //题目没说这里的s 一定小于 e 啊!!!!!! update(1, s, e-1, i); } for(int i = 1; i <= n-1; i++){ int s = 0, t = 0; query(1, i, s, t); vec_s[s].push_back(i); vec_t[t].push_back(i); } int sum = 0; for(int i = 1; i <= m; i++){ for(int j = 0; j < vec_s[i].size(); j++){ sum += cost[vec_s[i][j]]; } printf("%d\n", sum); for(int j = 0; j < vec_t[i].size(); j++) sum -= cost[vec_t[i][j]]; } } return 0; }
相关文章推荐
- hdu5861 维护最大最小值线段树
- Sliding Window(单调队列维护或线段树求区间最大最小值)
- nyoj 1185 最大最小值【线段树最大值最小值维护】
- poj3264 线段树维护最大值最小值
- poj 2823 poj 3264 线段树维护最大最小值
- HDU 4302 线段树单点更新,维护区间最大最小值
- hdu 6070 Dirt Ratio(二分+线段树维护区间最小值)
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
- nyoj 最大最小值 1185 (线段树)
- HDU 2795 放模板 (线段树_维护最大值,好题)
- 动态区间最大值最小值区间和查询,支持区间设置,线段树
- 51nod 1376【线段树维护区间最大值】
- 线段树(维护最大值):HDU Billboard
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
- 【NOIP2012】 CODE[VS] 1217 借教室(线段树维护区间最小值)
- POJ 3264 Balanced Lineup(线段树—求区间最大值与最小值差)
- hdoj 2795 Billboard 【线段树 单点更新 + 维护区间最大值】
- hdoj 1541 Stars【线段树单点更新+最大值维护】
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
- NYOJ 1185 最大最小值 (线段树区间最值 水)