ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF765F Souvenirs

2022-02-22 20:03:03  阅读:158  来源: 互联网

标签:rt return int ret Souvenirs CF765F define


https://www.luogu.com.cn/problem/CF765F

挺不错的一道题,首先考虑扫描线,对于每个\(i\),找\(j<i,a[j]>a[i], j\)最大的

用权值线段树可以轻易维护

假设找到一个\(j\),然后再找\((a[i],a[j])\)之间的

时间复杂度不优

考虑再找到的一个是\(j'\)

发现必须要满足\(a[j']-a[i]<a[j]-a[i]\) 且 \(a[j']-a[i]<a[j]-a[j']\)

综合一下如果\(j'\)能贡献答案的话就必须满足第二条式子

移动一下项可以得到

\(2a[j']<a[j]+a[i] \\ a[j']<\frac{a[j]+a[i]}{2}\)

直接找即可

然后再用一个树状数组维护后缀最大值

code:

#include<bits/stdc++.h>
#define N 300050
#define pii pair<int, int>
#define ls ch[rt][0]
#define rs ch[rt][1]
#define fi first
#define se second
using namespace std;
const int lim = 1e9;
int ma[N << 5], ch[N << 5][2], tot, root;
void add(int &rt, int l, int r, int x, int o) {
    if(!rt) rt = ++ tot;
    ma[rt] = max(ma[rt], o);
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(x <= mid) add(ls, l, mid, x, o);
    else add(rs, mid + 1, r, x, o); 
}
int query(int rt, int l, int r, int L, int R) {
    if(L > R) return 0;
    if(!rt) return 0;
    if(L <= l && r <= R) return ma[rt];
    int mid = (l + r) >> 1, ret = 0;
    if(L <= mid) ret = query(ls, l, mid, L, R);
    if(R > mid) ret = max(ret, query(rs, mid + 1, r, L, R));
    return ret;
}
#define lowbit(x) (x & - x)
int t[N], n, a[N];
void update(int x, int y) {
    for(; x; x -= lowbit(x)) t[x] = min(t[x], y);
}
int ask(int x) {
    int ret = lim;
    for(; x <= n; x += lowbit(x)) ret = min(ret, t[x]);
    return ret;
}
void clr() {
    for(int i = 0; i <= n; i ++) t[i] = lim;
    for(int i = 0; i <= tot; i ++) ch[i][0] = ch[i][1] = ma[i] = 0;
    tot = root = 0;
}
vector<pii > q[N];
int ans[N], m;
void solve() {
    clr();    
    for(int i = 1; i <= n; i ++) {
        int pos = query(root, 0, lim, a[i], lim);
        while(pos) {
            update(pos, a[pos] - a[i]);
            pos = query(root, 0, lim, a[i], (a[i] + a[pos] + 1) / 2 - 1);
        }
         add(root, 0, lim, a[i], i);
        for(auto it : q[i]) {
            ans[it.se] = min(ans[it.se], ask(it.fi));
        }
    }
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    scanf("%d", &m);
    for(int i = 1; i <= m; i ++) {
        int l, r;
        scanf("%d%d", &l, &r);
        q[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= m; i ++) ans[i] = lim;

    solve();
    for(int i = 1; i <= n; i ++) a[i] = lim - a[i];
    solve();
    for(int i = 1; i <= m; i ++) printf("%d\n", ans[i]);
    return 0;
}

标签:rt,return,int,ret,Souvenirs,CF765F,define
来源: https://www.cnblogs.com/lahlah/p/15924721.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有