zoukankan      html  css  js  c++  java
  • luogu 4587

    假设当前已经组合好了 $[1, x]$ ,设 $ans = x + 1$ ;显然初始时 $x = 0, ans = 1$
    我们另 $y = sum_{i = l} ^ {r} (w_i <= ans) * w_i$
    如果 $ans <= y$,说明除了组合出 $[1, x]$ 中的数,
    一定存在一个数满足 $<=x+1$
    这个时候 $[1, y]$ 都可以组合出来,另 $ans = y + 1$ ;
    如果 $ans>y$ ,说明除了组合出 $[1, x]$的数,
    其余所有的数均 $> x + 1$ ,这样当前的 $ans$ 就是答案了
    统计一个区间内 $<=k$ 的数的和可以用主席树来是实现

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    const int N = 1e5 + 10;
    
    int W[N * 20], Root[N], Lson[N * 20], Rson[N * 20];
    int n, A[N], B[N];
    
    #define gc getchar()
    inline int read() {
        int x = 0; char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x; 
    }
    
    int Seg_js;
    void Fill(int x, int y) {W[x] = W[y]; Lson[x] = Lson[y]; Rson[x] = Rson[y];}
    
    void Insert(int &jd, int l, int r, int x, int num) {
        Fill(++ Seg_js, jd);
        jd = Seg_js;
        W[jd] += num;
        if(l == r) return ; 
        int mid = (l + r) >> 1;
        if(x <= mid) Insert(Lson[jd], l, mid, x, num);
        else Insert(Rson[jd], mid + 1, r, x, num);
    }
    
    int Answer;
    
    void Sec_A(int jd1, int jd2, int l, int r, int x) {
        if(l == r) {Answer += (W[jd2] - W[jd1]); return;}
        int mid = (l + r) >> 1;
        if(x <= mid) Sec_A(Lson[jd1], Lson[jd2], l, mid, x);
        else {
            Answer += (W[Lson[jd2]] - W[Lson[jd1]]);
            Sec_A(Rson[jd1], Rson[jd2], mid + 1, r, x);
        }
    }
    
    int Len;
    
    inline int Find(int x) {
        int l = 1, r = Len, ret;
        while(l <= r) {
            int mid = (l + r) >> 1;
            if(B[mid] <= x) ret = mid, l = mid + 1;
            else r = mid - 1;
        }
        return ret;
    }
    
    int main() {
        n = read();
        for(int i = 1; i <= n; i ++) A[i] = read(), B[i] = A[i];
        sort(B + 1, B + n + 1);
        Len = unique(B + 1, B + n + 1) - B - 1;
        for(int i = 1; i <= n; i ++) {
            int t = lower_bound(B + 1, B + Len + 1, A[i]) - B;
            Root[i] = Root[i - 1];
            Insert(Root[i], 1, Len, t, A[i]);
        }
        int Q = read();
        for(; Q; Q --) {
            int l = read(), r = read();
            int Ans = 1;
            while(1) {
                int tmp = Find(Ans);
                Answer = 0;
                Sec_A(Root[l - 1], Root[r], 1, Len, tmp);
                if(Answer >= Ans) Ans = Answer + 1;
                else break;
            }
            printf("%d
    ", Ans);
        }
        return 0;
    }
  • 相关阅读:
    touch测试
    JS动画代码
    前端css、javascript在线工具
    横向广告(商品)滚动
    写点js的小函数(一)
    HTML5 css reset
    JS新API标准 地理定位(navigator.geolocation)
    写点js的小函数(二、文本框的提示)
    传说中的comet(ajax版)?
    lhgdialog 4.2.0 正式版发布
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9506557.html
Copyright © 2011-2022 走看看