zoukankan      html  css  js  c++  java
  • Luogu 4602 [CTSC2018]混合果汁

    BZOJ 5343

    福利题。

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

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

    当然也可以整体二分。

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

    Code:

    #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, '
    ');
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    NET Framework 4.5新特性 (二) 控制台支持 Unicode (UTF-16) 编码
    Openstack架构及配置
    MariaDB知识点总结03--从主+多主集群
    MariaDB知识点总结02--日志+备份
    Linux服务知识点总结
    MariaDB基本知识点总结01--介绍+语句
    Openstack知识点总结
    K8S知识点总结
    Docker知识点总结
    Zabbix介绍及安装(1)
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/10425348.html
Copyright © 2011-2022 走看看