hihoCoder 1169 猜数字 (线段树,离线处理)

来源:互联网 发布:继承在编程方面翻译为 编辑:程序博客网 时间:2024/06/04 19:49

题意:

每次询问求出区间最接近k的数对应的差。

题解:

离线操作,两次排序,计算两次,第一次将询问和数字根据k从小到大排序,碰到询问只要查询区间的最大值跟定是最靠近k的,相反第二次是从大到小排序,求最小值是最靠近k的,两次计算的值取最小值即可。

#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<string>#include<vector>#include<queue>#include<map>#include<set>#include<stack>#define B(x) (1<<(x))using namespace std;typedef long long ll;typedef unsigned long long ull;const int oo = 0x3f3f3f3f;const ll OO = 0x3f3f3f3f3f3f3f3f;const double eps = 1e-9;#define lson rt<<1#define rson rt<<1|1void cmax(int& a, int b){ if (b > a)a = b; }void cmin(int& a, int b){ if (b < a)a = b; }void cmax(ll& a, ll b){ if (b > a)a = b; }void cmin(ll& a, ll b){ if (b < a)a = b; }void cmax(double& a, double b){ if (a - b < eps) a = b; }void cmin(double& a, double b){ if (b - a < eps) a = b; }void add(int& a, int b, int mod){ a = (a + b) % mod; }void add(ll& a, ll b, ll mod){ a = (a + b) % mod; }const ll MOD = 1000000007;const int maxn = 210000;struct SegTree{int l, r, max, min;int mid(){ return (l + r) >> 1; }}tree[maxn << 2];struct Query{int l, r, k, id, f;}q[maxn << 1];int ans[maxn];void push_up(int rt){tree[rt].max = max(tree[lson].max, tree[rson].max);tree[rt].min = min(tree[lson].min, tree[rson].min);}void build(int l, int r, int rt){tree[rt].l = l;tree[rt].r = r;tree[rt].max = -oo;tree[rt].min = oo;if (l == r) return;int mid = (l + r) >> 1;build(l, mid, lson);build(mid + 1, r, rson);push_up(rt);}void update(int p, int v, int rt){if (tree[rt].l == tree[rt].r&&tree[rt].r == p){tree[rt].max = tree[rt].min = v;return;}int mid = tree[rt].mid();if (p <= mid) update(p, v, lson);else if (p >= mid + 1) update(p, v, rson);push_up(rt);}int get_max(int l, int r, int rt){if (l <= tree[rt].l && tree[rt].r <= r){return tree[rt].max;}int mid = tree[rt].mid();int res = -oo;if (l <= mid) cmax(res, get_max(l, r, lson));if (mid + 1 <= r) cmax(res, get_max(l, r, rson));return res;}int get_min(int l, int r, int rt){if (l <= tree[rt].l && tree[rt].r <= r){return tree[rt].min;}int mid = tree[rt].mid();int res = oo;if (l <= mid) cmin(res, get_min(l, r, lson));if (mid + 1 <= r) cmin(res, get_min(l, r, rson));return res;}bool cmp1(Query q1, Query q2){if (q1.k == q2.k)return q1.f < q2.f;return q1.k < q2.k;}bool cmp2(Query q1, Query q2){if (q1.k == q2.k)return q1.f < q2.f;return q1.k > q2.k;}int main(){//freopen("E:\\read.txt", "r", stdin);int T, n, Q, nn, cas = 1;scanf("%d", &T);while (T--){scanf("%d %d", &n, &Q);for (int i = 1; i <= n; i++){scanf("%d", &q[i].k);q[i].l = i;q[i].f = 0;}nn = n;for (int i = 1; i <= Q; i++){++nn;scanf("%d %d %d", &q[nn].l, &q[nn].r, &q[nn].k);q[nn].f = 1;q[nn].id = i;}build(1, n, 1);sort(q + 1, q + 1 + nn, cmp1);for (int i = 1; i <= nn; i++){if (q[i].f == 0) update(q[i].l, q[i].k, 1);else ans[q[i].id] = q[i].k - get_max(q[i].l, q[i].r, 1);}build(1, n, 1);sort(q + 1, q + 1 + nn, cmp2);for (int i = 1; i <= nn; i++){if (q[i].f == 0) update(q[i].l, q[i].k, 1);else{int tmp = get_min(q[i].l, q[i].r, 1);if (tmp == oo) continue;cmin(ans[q[i].id], tmp - q[i].k);}}printf("Case #%d:\n", cas++);for (int i = 1; i <= Q; i++)printf("%d\n", ans[i]);}return 0;}



0 0
原创粉丝点击