zoukankan      html  css  js  c++  java
  • HDU

    思路:我们定义F(x) 为以x点为起点,向后(a - b)个里面有多少个白球,虽然x的范围是LL范围内的,但是白球的

    个数只有1e5, 那么我们可以把连续一段相同的离散化到一起, 对于一个确定的长度为a的段, Bob选择留下F(x)

    最小的那一个,这个可以用st表求出来, 那么对于Alice来说,对于函数F(x)离散化到一起的值域(p - q) , 我们如果

    要在(p - q)之间选一个起点那么p这个点是最优的点。那么我们枚举这些p,选一个答案的最大值。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PII pair<int, int>
    #define PLI pair<LL, int>
    #define ull unsigned long long
    using namespace std;
    
    const int N = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    
    ull n, L, R, a, b, c, dis, tot, p[N], range[N];
    int f[N], Log[N];
    
    struct ST {
        int dp[N][20],ty;
        void build(int n, int b[], int _ty) {
            ty = _ty;
            for(int i = 1; i <= n; i++) dp[i][0] = ty*b[i];
            for(int j = 1; j <= Log[n]; j++)
                for(int i = 1; i+(1<<j)-1 <= n; i++)
                    dp[i][j] = max(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
        }
        int query(int x, int y) {
            if(x > y) return 0;
            int k = Log[y - x + 1];
            return ty * max(dp[x][k], dp[y-(1<<k)+1][k]);
        }
    } rmq;
    
    int main() {
        for(int i = -(Log[0]=-1); i < N; i++)
            Log[i] = Log[i - 1] + ((i & (i - 1)) == 0);
        while(scanf("%llu", &n) != EOF) {
            tot = 0;
            scanf("%llu%llu%llu%llu", &L, &R, &a, &b);
            for(int i = 1; i <= n; i++)
                scanf("%llu", &p[i]);
            if(a == b) {
                puts("0");
            } else {
                c = a - b;
                for(ull i = L, j = 1, k = 1; i <= R; i += dis) {
                    while(k <= n && i > p[k]) k++;
                    while(j <= n && i+c-1 >= p[j]) j++;
                    f[++tot] = j - k;
                    dis = R - i + 1;
                    if(k <= n) dis = min(dis, p[k]-i+1);
                    if(j <= n) dis = min(dis, p[j]-i-c+1);
                    range[tot] = i;
                }
                rmq.build(tot, f, -1);
                int ans = 0;
                for(int i = 1, j = 1; i <= tot; i++) {
                    if(range[i]+a-1 > R) break;
                    while(j <= tot && range[j] <= range[i]+a-c) j++;
                    ans = max(ans, rmq.query(i, j-1));
                }
                printf("%llu
    ", ans);
            }
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    构建之法阅读心得(九)
    构建之法阅读心得(八)
    构建之法阅读心得(七)
    构建之法阅读心得(六)
    构建之法阅读心得(五)
    构建之法阅读心得(四)
    一组阶段小记之读构建之法(三)
    暑期学习总结
    软工综合实践 学习笔记02
    软工综合实践 学习笔记01
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9778736.html
Copyright © 2011-2022 走看看