zoukankan      html  css  js  c++  java
  • Sorted Subsegments

    https://www.hackerrank.com/contests/101hack38/challenges/sorted-subsegments/problem

    首先要注意到可以二分答案,比如当前位置是4,二分答案是2,是可以的,往大的找找就好。

    然后把 >= 2的变成1, < 2的变成0,然后就对这个01串排序了。

    01串排序可以用线段树加速,因为区间里1的个数是固定的,排序区间L, R,只相当于把区间里1的个数全部往右移动。

    然后就可以直接用线段树查找区间总和 + 覆盖即可。

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    #define lson L, mid, cur << 1
    #define rson mid + 1, R, cur << 1 | 1
    #define root 1, n, 1
    const int maxn = 75000 + 20;
    int sum[maxn << 2], add[maxn << 2];
    int a[maxn];
    int n, q, k;
    struct Node {
        int L, R;
    }query[maxn];
    void pushUp(int cur) {
        sum[cur] = sum[cur << 1] + sum[cur << 1 | 1];
    }
    void build(int L, int R, int cur, int val) {
        if (L == R) {
            sum[cur] = a[L] >= val;
            return ;
        }
        int mid = (L + R) >> 1;
        build(lson, val);
        build(rson, val);
        pushUp(cur);
    }
    void pushDown(int cur, int has) {
        if (add[cur] != -1) {
            add[cur << 1] = add[cur << 1 | 1] = add[cur];
            sum[cur << 1] = (has - (has >> 1)) * add[cur];
            sum[cur << 1 | 1] = (has >> 1) * add[cur];
            add[cur] = -1;
        }
    }
    int ask(int be, int en, int L, int R, int cur) {
        if (L >= be && R <= en) return sum[cur];
        pushDown(cur, R - L + 1);
        int mid = (L + R) >> 1;
        int ans = 0;
        if (be <= mid) ans += ask(be, en, lson);
        if (en > mid) ans += ask(be, en, rson);
        return ans;
    }
    void upDate(int be, int en, int val, int L, int R, int cur) {
        if (be > en) return;
        if (L >= be && R <= en) {
            add[cur] = val;
            sum[cur] = (R - L + 1) * val;
            return;
        }
        pushDown(cur, R - L + 1);
        int mid = (L + R) >> 1;
        if (be <= mid) upDate(be, en, val, lson);
        if (en > mid) upDate(be, en, val, rson);
        pushUp(cur);
    }
    bool check(LL val) {
        build(root, val);
        memset(add, -1, sizeof add);
        for (int i = 1; i <= q; ++i) {
            int has = query[i].R - query[i].L + 1;
            int one = ask(query[i].L, query[i].R, root);
            upDate(query[i].L, query[i].L + has - one - 1, 0, root);
            upDate(query[i].L + has - one, query[i].R, 1, root);
        }
        return ask(k, k, root);
    }
    void work() {
        scanf("%d%d%d", &n, &q, &k);
        ++k;
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
        }
        for (int i = 1; i <= q; ++i) {
            scanf("%d%d", &query[i].L, &query[i].R);
            query[i].L++, query[i].R++;
        }
    //    build(root, 4);
    //    upDate(1, 3, 0, root);
    //    upDate(4, 4, 1, root);
    //    printf("%d
    ", ask(1, 1, root));
    
        LL be = -1e9, en = 1e9;
        while (be <= en) {
            LL mid = (be + en) >> 1;
            if (check(mid)) be = mid + 1;
            else en = mid - 1;
        }
        cout << en << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
  • 相关阅读:
    完美解决IE8有两个进程的问题
    用ccproxy + stunnel做个加密代理
    Hyper-V 共享式网络链接 端口映射
    NET Framework 4.0的安装失败处理
    c#控制IE浏览器自动点击等事件WebBrowser,mshtml.IHTMLDocument2 .
    设置IE8 多个Table只产生一个进程
    SSH Secure Shell Client中文乱码的解决办法
    OOD设计模式
    MVC设计模式
    乐观锁和悲观锁
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7231847.html
Copyright © 2011-2022 走看看