ICode9

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

CF678F Lena and Queries

2021-12-17 07:31:11  阅读:165  来源: 互联网

标签:Lena return int ll mid Queries top CF678F lld


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

首先一眼线段树分治

然后线段树上每个节点建一个凸包,在上面三分即可

code:


#include<bits/stdc++.h>
#define ll long long
#define N 300050
using namespace std;
const ll inf = 2e18;
struct P {
    ll x, y;
    P operator + (const P o) {return (P){x + o.x, y + o.y}; }
    P operator - (const P o) {return (P){x - o.x, y - o.y}; }
    ll operator * (const P o) {return x * o.y - y * o.x; }
    bool operator < (const P o) const {return x == o.x? y < o.y : x < o.x; }
} a[N], sta[N];

ll cross(P a, P b, P c) {
    return (b - a) * (c - a);
}
ll calc(P o, ll k) {
    //printf("%lld %lld  %lld\n", o.x, o.y, k);
    return k * o.x + o.y;
}
struct TB {
    vector<P> v;
    void push(P x) {v.push_back(x);}
    void px() {
        sort(v.begin(), v.end());
        //printf("%d\n", v.size());
        //for(auto x : v) printf("(%lld %lld) ", x.x, x.y); printf("\n");
        int top = 0; 
        for(auto x : v) {
            while(top > 1 && cross(sta[top - 1], sta[top], x) >= 0) top --;
            sta[++ top] = x;
        }
        v.clear();
        for(int i = 1; i <= top; i ++) v.push_back(sta[i]);
        //printf("** %d\n", top);
    }
    ll query(ll k) {
        if(!v.size()) return - inf;
        int l = 0, r = v.size() - 1;
        while(l + 1 < r) {
            int mid = (l + r) >> 1;
            if(calc(v[mid], k) < calc(v[mid + 1], k)) l = mid;
            else r = mid;
        }
    //    printf("%lld   (%lld %lld)  %lld  \n", k, v[0].x, v[0].y, calc(v[0], k));
        return max(calc(v[l], k), calc(v[r], k));
    }
} V[N << 3];

#define ls (rt << 1)
#define rs (rt << 1 | 1)
void insert(int rt, int l, int r, int L, int R, P o) {
    if(L <= l && r <= R) {
    //    printf("** %d %d  %d\n", l, r, o.x);
        V[rt].push(o);
        return ;
    }
    int mid = (l + r) >> 1;
    if(L <= mid) insert(ls, l, mid, L, R, o);
    if(R > mid) insert(rs, mid + 1, r, L, R, o);
}
void build(int rt, int l, int r) {
    V[rt].px();
    if(l == r) return ;
    int mid = (l + r) >> 1;
    build(ls, l, mid), build(rs, mid + 1, r);
}
ll query(int rt, int l, int r, int x, ll k) {
    ll ret = V[rt].query(k);
    //printf("   %d %d %d %d  %lld  %d\n", l, r, L, R, k, (int)V[rt].v.size());
    if(l == r) return ret;
    int mid = (l + r) >> 1;
    if(x <= mid) ret = max(ret, query(ls, l, mid, x, k));
    else ret = max(ret, query(rs, mid + 1, r, x, k));
    return ret;
}
int n, o[N], R[N], k[N];
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) {
        int x;
        scanf("%d", &o[i]);
        if(o[i] == 1) {
            scanf("%lld%lld", &a[i].x, &a[i].y);
            R[i] = n;
        } 
        if(o[i] == 2) {
            scanf("%d", &x);
            R[x] = i;
        }
        if(o[i] == 3) {
            scanf("%d", &k[i]);
        }
    }

    for(int i = 1; i <= n; i ++) if(R[i]) {
        insert(1, 1, n, i, R[i], a[i]);
    }
    build(1, 1, n);

    for(int i = 1; i <= n; i ++) if(o[i] == 3) {
        ll ret = query(1, 1, n, i, k[i]);
        if(ret == -inf) printf("EMPTY SET\n");
        else printf("%lld\n", ret);
    }
    return 0;
}

标签:Lena,return,int,ll,mid,Queries,top,CF678F,lld
来源: https://www.cnblogs.com/lahlah/p/15700701.html

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

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

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

ICode9版权所有