Luogu 4602 [CTSC2018]混合果汁

BZOJ 5343

福利题。

对于每一个询问可以二分$d$,然后把满足条件的果汁按照$p$从小到大排序贪心地取$L$升看看满不满足价格的条件。

那么按照$p$建立权值主席树,$chk$的时候在主席树上走一走算出价格即可。

当然也可以整体二分。

时间复杂度都是$O(nlog^2n)$。

Code:

Luogu 4602 [CTSC2018]混合果汁
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

const int N = 1e5 + 5;
const ll inf = 1LL << 60;

int n, qn, tot = 0, pos[N], buc[N];

struct Item {
    int d, cost, lim;
    
    inline Item(int D = 0, int Cost = 0, int Lim = 0) {
        d = D, cost = Cost, lim = Lim;
    }
    
    friend bool operator < (const Item x, const Item y) {
        return x.d > y.d;
    }
    
} a[N];

namespace Fread {
    const int L = 1 << 15;
    
    char buffer[L], *S, *T;
    
    inline char Getchar() {
        if(S == T) {
            T = (S = buffer) + fread(buffer, 1, L, stdin);
            if(S == T) return EOF;
        }
        return *S++;
    }
    
    template <class T> 
    inline void read(T &X) {
        char ch; T op = 1;
        for(ch = Getchar(); ch > '9' || ch < '0'; ch = Getchar())
            if(ch == '-') op = -1;
        for(X = 0; ch >= '0' && ch <= '9'; ch = Getchar()) 
            X = (X << 1) + (X << 3) + ch - '0'; 
        X *= op;
    }
    
} using namespace Fread;   

namespace Fwrite {
    const int L = 1 << 15;
    
    char buf[L], *pp = buf;
    
    void Putchar(const char c) {
        if(pp - buf == L) fwrite(buf, 1, L, stdout), pp = buf;
        *pp++ = c;
    }
    
    template<typename T>
    void print(T x) {
        if(x < 0) {
            Putchar('-');
            x = -x;
        }
        if(x > 9) print(x / 10);
        Putchar(x % 10 + '0');
    }
    
    void fsh() {
        fwrite(buf, 1, pp - buf, stdout);
        pp = buf;
    }
    
    template <typename T>
    inline void write(T x, char ch = 0) {
        print(x);
        if (ch != 0) Putchar(ch);
        fsh();
    }

} using namespace Fwrite;

namespace SegT {
    struct Node {
        int lc, rc;
        ll sum, cnt;
    } s[N * 30];
    
    int root[N], nodeCnt = 0;
    
    #define lc(p) s[p].lc
    #define rc(p) s[p].rc
    #define sum(p) s[p].sum
    #define cnt(p) s[p].cnt
    #define mid ((l + r) >> 1)
    
    void ins(int &p, int l, int r, int x, int v, int pre) {
        s[p = ++nodeCnt] = s[pre];
        cnt(p) += 1LL * v, sum(p) += 1LL * v * buc[x];
        if (l == r) return;
        
        if (x <= mid) ins(lc(p), l, mid, x, v, lc(pre));
        else ins(rc(p), mid + 1, r, x, v, rc(pre));
    }
    
    ll query(int p, int l, int r, ll cur) {
        if (l == r) return cur > cnt(p) ? inf : cur * buc[l];
        ll now = cnt(lc(p));
        if (cur <= now) return query(lc(p), l, mid, cur);
        else return sum(lc(p)) + query(rc(p), mid + 1, r, cur - now);
    }
    
    #undef mid
    
} using namespace SegT;

inline bool chk(int mid, ll x, ll y) {
    if (cnt(root[pos[a[mid].d]]) < y) return 0;
    ll now = query(root[pos[a[mid].d]], 1, tot, y);
    return now <= x;
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("Sample.txt", "r", stdin);
    #endif
    
    read(n), read(qn);
    for (int i = 1; i <= n; i++) {
        read(a[i].d), read(a[i].cost), read(a[i].lim);
        buc[++tot] = a[i].cost;
    }
    
    sort(buc + 1, buc + 1 + tot);
    tot = unique(buc + 1, buc + 1 + tot) - buc - 1;
    for (int i = 1; i <= n; i++)
        a[i].cost = lower_bound(buc + 1, buc + 1 + tot, a[i].cost) - buc;
    
    sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; i++) {
        ins(root[i], 1, tot, a[i].cost, a[i].lim, root[i - 1]);
        pos[a[i].d] = i;
    }
    
    for (ll x, y; qn--; ) {
        read(x), read(y);
/*        if (y > cnt(root[n])) {
            puts("-1");
            continue;
        }   */
        
        int ln = 1, rn = n, mid, res = 0;
        for (; ln <= rn; ) {
            mid = (ln + rn) / 2;
            if (chk(mid, x, y)) rn = mid - 1, res = mid;
            else ln = mid + 1;
        }
        
        write((!res) ? -1 : a[res].d, '\n');
    }
    
    return 0;
}
View Code

 

上一篇:[分治FFT]「CTSC2018」青蕈领主


下一篇:验证码识别