暑假前专题题解---数据结构---F

题目转送门:http://qscoj.cn/#/problem/show/1921

因为A很大,所以需要先离散化,然后建树,对于每个A - len 的位置二分查找位置,用线段树询问区间和最大最小值即可

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
struct node { int A,B; }p[maxn];
int sum[maxn<<2],maxx[maxn<<2],minn[maxn<<2];
int sum1,max1 = -INT_MAX,min1 = INT_MAX;
int n,c,len;
void up(int id){
    sum[id] = sum[id<<1] + sum[id<<1|1];
    maxx[id] = max(maxx[id<<1] , maxx[id<<1|1]);
    minn[id] = min(minn[id<<1] , minn[id<<1|1]);
}
void build(int l,int r,int id){
    if (l == r){
        sum[id] = p[l].B;
        maxx[id] = p[l].B;
        minn[id] = p[l].B;
        return ;
    }
    int mid = (l + r) >> 1;
    build(l, mid, id<<1);
    build(mid+1, r, id<<1|1);
    up(id);
}
void query(int l,int r,int L,int R,int id){
    if (L <= l && r <= R){
        sum1 += sum[id];
        max1 = max(max1, maxx[id]);
        min1 = min(min1, minn[id]);
        return;
    }
    int mid = (l + r )>> 1;
    if (L <= mid) query(l, mid, L, R, id<<1);
    if (R > mid) query(mid+1, r, L, R, id<<1|1);
}
int low(int v){
    int l = 1, r = n;
    while (l != r) {
        int mid = (l + r) >> 1;
        if (p[mid].A > v) r = mid;
        else l = mid + 1;
    }
    return l;
}
int solve(string k,string fun){
    int cnt = 0;
    for (int i=2; i<=n; i++) {
        int x = low(p[i].A - len);
        while (p[x].A > p[i].A - len && x != 1) x--;
        while (p[x].A < p[i].A - len) x++;
        query(1, n, x, i-1, 1);
        if (k == "gt"){
            if (fun == "min"){
                if (p[i].B > min1) cnt++;
            }else if (fun == "max"){
                if (p[i].B > max1) cnt++;
            }else if (fun == "avg"){
                if (p[i].B*(i-x) > sum1) cnt++;
            }
        }else if (k == "lt"){
            if (fun == "min"){
                if (p[i].B < min1) cnt++;
            }else if (fun == "max"){
                if (p[i].B < max1) cnt++;
            }else if (fun == "avg"){
                if (p[i].B*(i-x) < sum1) cnt++;
            }
        }
        sum1 = 0; max1 = -INT_MAX; min1 = INT_MAX;
    }
    return cnt;
}
int main(){
    cin >> n >> c;
    for (int i=1; i<=n; i++)
        cin >> p[i].A >> p[i].B;
    build(1, n, 1);
    string k,fun;
    for (int i=0; i<c; i++) {
        cin >> k >> fun >> len;
        cout << solve(k, fun) << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/CCCCTong/article/details/81391842