HDU 5861 Road (线段树区间设值)
来源:互联网 发布:php培训机构哪个好 编辑:程序博客网 时间:2024/05/14 20:26
题意:一条线段上n个点将线段分成n-1份,点的编号从左往右1~n,每条路你只能打开一次,打开后每天都收费,打
开后你可以关上,但是关上后这条路就再也不能打开了。每条路还有一个花费,q次询问,每次询问给你一个区间,
表示你需要从区间左端点走到右端点,要求走的路都是打开的,然后问你在保证你能过去的情况下,每天的最小花
费。
题意:我们可以想到求出每条路的第一次用的时间和最后一次用的时间(这里可以用线段树区间设值实现,求最后一
次时间就是从第一天开始每次将区间的值设为i,最后每个点的值即为最后一次用的时间,求第一次反过来计算一遍就
行),知道每条路的第一次和最后一次的使用时间后,我们可以将每条路拆成两个点,分别为(st, cost), (et+1, -cost),
然后对这些点按时间排序,然后对枚举q,枚举到第i天,就把t<=i的都在BIT更新一下。更新完求下整个区间的和即为
今天的最小花费。
有个坑,,给你的区间(u, v)左右端点不一定u < v
代码:
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 2e5+5;ll sum[maxn*4], lazy[maxn*4], sset[maxn*4], n, q;ll a[maxn];void pushup(int root, int l, int r){ sum[root] = sum[root*2]+sum[root*2+1];}void pushdown(int root, int l, int r){ int mid = (l+r)/2; if(sset[root] != -1) { lazy[root*2] = lazy[root*2+1] = 0; sset[root*2] = sset[root*2+1] = sset[root]; sum[root*2] = sset[root]*(mid-l+1); sum[root*2+1] = sset[root]*(r-mid); sset[root] = -1; } if(lazy[root]) { lazy[root*2] += lazy[root]; lazy[root*2+1] += lazy[root]; sum[root*2] += lazy[root]*(mid-l+1); sum[root*2+1] += lazy[root]*(r-mid); lazy[root] = 0; }}void Set(int root, int l, int r, int i, int j, ll val){ if(i <= l && j >= r) { sset[root] = val; lazy[root] = 0; sum[root] = val*(r-l+1); return ; } pushdown(root, l, r); int mid = (l+r)/2; if(i <= mid) Set(root*2, l, mid, i, j, val); if(j > mid) Set(root*2+1, mid+1, r, i, j, val); pushup(root, l, r);}void update(int root, int l, int r, int i, int j, int val){ if(i <= l && j >= r) { lazy[root] += val; sum[root] += val*(r-l+1); return ; } pushdown(root, l, r); int mid = (l+r)/2; if(i <= mid) update(root*2, l, mid, i, j, val); if(j > mid) update(root*2+1, mid+1, r, i, j, val); pushup(root, l, r);}ll query(int root, int l, int r, int i, int j){ if(i <= l && j >= r) return sum[root]; pushdown(root, l, r); int mid = (l+r)/2; ll res = 0; if(i <= mid) res += query(root*2, l, mid, i, j); if(j > mid) res += query(root*2+1, mid+1, r, i, j); pushup(root, l, r); return res;}int ql[maxn], qr[maxn];struct node{ int pos, time; ll cost; node(){} node(int pp, int tt, ll cc): pos(pp), time(tt), cost(cc) {} bool operator < (const node &a) const { return time < a.time; }}aa[maxn*3];ll tree[maxn];int lowbit(int x){ return x&(-x);}void update(int pos, int val){ while(pos < maxn) { tree[pos] += val; pos += lowbit(pos); }}ll query(int pos){ ll res = 0; while(pos) { res += tree[pos]; pos -= lowbit(pos); } return res;}int main(void){ while(cin >> n >> q) { memset(tree, 0, sizeof(tree)); memset(sum, 0, sizeof(sum)); memset(lazy, 0, sizeof(lazy)); memset(sset, 0, sizeof(sset)); for(int i = 1; i < n; i++) scanf("%lld", &a[i]); for(int i = 1; i <= q; i++) { scanf("%d%d", &ql[i], &qr[i]); if(ql[i] > qr[i]) swap(ql[i], qr[i]); qr[i]--; Set(1, 1, n, ql[i], qr[i], i); } int cnt = 0; for(int i = 1; i <= n; i++) { int tmp = query(1, 1, n, i, i); if(tmp) aa[cnt++] = node(i, tmp+1, -a[i]); } memset(sum, 0, sizeof(sum)); memset(lazy, 0, sizeof(lazy)); memset(sset, 0, sizeof(sset)); for(int i = q; i >= 1; i--) Set(1, 1, n, ql[i], qr[i], i); for(int i = 1; i <= n; i++) { int tmp = query(1, 1, n, i, i); if(tmp) aa[cnt++] = node(i, tmp, a[i]); } sort(aa, aa+cnt); int p = 0; for(int i = 1; i <= q; i++) { while(p < cnt && aa[p].time <= i) { update(aa[p].pos, aa[p].cost); p++; } printf("%lld\n", query(maxn-1)); } } return 0;}
阅读全文
1 0
- HDU 5861 Road (线段树区间设值)
- hdu 5861 Road 线段树区间更新
- HDU 5861 Road(线段树)
- HDU 1698 Just a Hook 数据结构+线段树+区间修改(设值)+区间求和
- HDU 5861 Road(线段树)
- HDU 5861 Road(线段树)
- 2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树区间更新+差分数组)
- HDU 5861 Road (线段树+树状数组)
- HDU 5861 Road (线段树或并查集)
- hdu 4578 区间线段树
- HDU 1698 线段树区间
- Uva 11992 Fast Matrix Operations(线段树区间设值与加操作)
- Educational Codeforces Round 23 F. MEX Queries(线段树区间设值)
- HDU 5861 Road (线段树) 2016 Multi-University Training Contest 10
- hdu 5861Road(2016 Multi-University Training Contest 10——线段树+扫描线)
- hdu 5861 (线段树,区间更新,单点查询)
- HDU 1754(zkw线段树-区间最值)
- HDU 4267 线段树区间内部某个值更新
- Spring Cloud netflix概览和架构设计
- spring boot slf4j 配置日志记录
- 微信小程序登陆及登陆状态保持前后端php代码 缓存redis
- python_lintcode_167链表求和
- jsp标签库和隐含对象的用法
- HDU 5861 Road (线段树区间设值)
- JS前端合并TABLE相同列的单元格
- C++17新特性简介
- oracle中修改表名语句
- Underscore简介
- 2019.09.12 字符串查找
- 什么是敏捷开发
- python中%r和%s的区别
- 微信登陆 (微信PC扫码授权登陆) 简单的php代码