现在的位置: 首页 > 综合 > 正文

CF 338E Optimize! (线段树)

2012年11月02日 ⁄ 综合 ⁄ 共 1741字 ⁄ 字号 评论关闭

转载请注明出处,谢谢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\n" , ans);
    return 0;
}   



抱歉!评论已关闭.