首页 > 代码库 > [luoguP2672] 推销员(贪心 + 树状数组 + 优先队列)
[luoguP2672] 推销员(贪心 + 树状数组 + 优先队列)
传送门
贪心。。。蒟蒻证明不会。。。
每一次找最大的即可,找出一次最大的,数列会分为左右两边,左边用stl优先队列维护,右边用树状数组维护。。
(线段树超时了。。。。)
代码
#include <queue>#include <cstdio>#include <iostream>#define N 100001#define ls now << 1#define rs now << 1 | 1#define max(x, y) (p[x].a * 2 + p[x].b > p[y].a * 2 + p[y].b ? (x) : (y))int n, last, now, ans, M[N];std::priority_queue <int> q; struct node{ int a, b;}p[N];inline int read(){ int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘; return x * f;}inline void add(int x, int d){ for(; x; x -= x & -x) M[x] = max(M[x], d);}inline int query(int x){ int ret = 0; for(; x <= n; x += x & -x) ret = max(ret, M[x]); return ret;}int main(){ int i, j, x; n = read(); for(i = 1; i <= n; i++) p[i].a = read(); for(i = 1; i <= n; i++) p[i].b = read(); for(i = 1; i <= n; i++) add(i, i); last = 0; for(i = 1; i <= n; i++) { now = query(last + 1); if(q.empty() || (q.top() < (p[now].a - p[last].a) * 2 + p[now].b)) { for(j = last + 1; j < now; j++) q.push(p[j].b); ans += (p[now].a - p[last].a) * 2 + p[now].b; last = now; } else { ans += q.top(); q.pop(); } printf("%d\n", ans); } return 0;}
[luoguP2672] 推销员(贪心 + 树状数组 + 优先队列)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。