zoukankan      html  css  js  c++  java
  • CF 338E Optimize! (线段树)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

    出题人题解没看懂。。。囧。

    然后看了下tourist代码,很短,也很好理解。。。

    我们将b排序之后,很显然如果组合的话肯定是贪心。

    那么对于a的某个子串a'要满足条件的话,那么显然是所有的数和b中最大元素相加不小于h。

    至少有len - 1个数的b中次大元素相加不小于h。。。以此类推那么首先预处理出对于a中的每个元素,和b串的哪些元素相加不小于h,显然是排序之后的二分

    那么选中某个区间的数,就是一个区间覆盖,判断b中第i大元素是否至少被覆盖了i次。

    为了方便,我们先将第i位减去一个i,然后判断区间最小值是否非负。

    #include <iostream>
    #include <queue>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #define lson step << 1
    #define rson step << 1 | 1
    using namespace std;
    typedef long long LL;
    const int N = 150005;
    struct Node {
        int left , right , add , mn;
    }L[N << 2];
    int n , h , b[N] , len , a[N];
    void bulid (int step , int l , int r) {
        L[step].left = l;
        L[step].right = r;
        L[step].add = 0;
        L[step].mn = 0;
        if (l == r) return ;
        int m = (l + r) >> 1;
        bulid (lson , l , m);
        bulid (rson , m + 1 , r);
    }
    void update (int step , int l , int r , int v);
    void push_down (int step) {
        int l = L[step].left , r = L[step].right , m = (l + r) >> 1;
        if (L[step].add) {
            update (lson , l , m , L[step].add);
            update (rson , m + 1 , r , L[step].add);
            L[step].add = 0;
        }
    }
    void push_up (int step) {
        L[step].mn = min (L[lson].mn , L[rson].mn);
    }
    void update (int step , int l , int r , int v) {
        if (L[step].left == l && L[step].right == r) {
            L[step].mn += v;
            L[step].add += v;
            return ;
        }
        push_down (step);
        int m = (L[step].left + L[step].right) >> 1;
        if (r <= m) update (lson , l , r , v);
        else if (l > m) update (rson , l , r , v);
        else {
            update (lson , l , m , v);
            update (rson , m + 1 , r , v);
        }
        push_up (step);
    } 
    int main() {
        int t;
        #ifndef ONLINE_JUDGE
            freopen ("input.txt" , "r" , stdin);
            // freopen ("output.txt" , "w" , stdout);
        #endif
        scanf ("%d %d %d" , &n , &len , &h);
        for (int i = 0 ; i < len ; i ++)
            scanf ("%d" , &b[i]);
        sort (b , b + len);
        bulid (1 , 0 , len);
        for (int i = 0 ; i < n ; i ++) {
            scanf ("%d" , &a[i]);
            a[i] = lower_bound (b , b + len , h - a[i]) - b;
        } 
        for (int i = 0 ; i < len ; i ++) 
            update (1 , i , i , -(i + 1));
        for (int i = 0 ; i < len - 1 ; i ++)
            update (1 , a[i] , len , 1);
        int ans = 0;
        for (int i = len - 1 ; i < n ; i ++) {
            update (1 , a[i] , len , 1);
            if (L[1].mn >= 0) ans ++;
            update (1 , a[i - len + 1] , len , -1);
        }
        printf ("%d
    " , ans);
        return 0;
    }   




  • 相关阅读:
    我的有道难题算法-双倍超立方数
    终于获取了SharePoint.OpenDocument对象打开的Word对象
    Eclipse下的项目管理插件介绍
    初识 sqlite 与 content provider 学习笔记
    android 官方文档中的一些错误收集
    android TraceView (图形化性能测试工具)使用入门笔记
    Texttospeech 入门与进阶学习笔记(android)
    Intent进阶 和 Intentfilter 学习笔记
    android UI设计属性中英对照表(未修订)
    android学习笔记7天打造一个简易网络Mp3播放器
  • 原文地址:https://www.cnblogs.com/riskyer/p/3266644.html
Copyright © 2011-2022 走看看