• gym102920I Stock Aalysis (2020-2021 ACM-ICPC, Asia Seoul Regional Contest) 三维偏序


    题意

    给一个长度为(n)的数组(a)(m)次询问,每次询问([S_i,E_i])中的子串和不超过(U_i)的最大值是多少。

    思路

    显然,可以发现是一个三位偏序题。询问(max{sum[l,r] | [-l,r,sum[l,r]]le[-S_i,E_i,U_i]})

    然后就有多种方法,可以分块+树状数组(O(sqrt{n}*logn*m+logn*n^2+(n^2+m)log(n^2+m))),询问+插入+排序),也可以用二维树状数组(O((n^2+m)log^2n+(n^2+m)log(n^2+m)))),也可以cdq分治((O((n^2+m)*log(n^2+m)*logn+(n^2+m)log(n^2+m))))+卡常。。

    代码

    cdq分治

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    const int maxn = 2e3 + 5;
    const int maxm = 2e5 + 5;
    const ll inf = 1e18;
    int a[maxn];
    ll sum[maxn];
    int s[maxm], e[maxm];
    ll u[maxm];
    
    struct IO{
    #define MAXSIZE (1 << 20)
    #define isdigit(x) (x >= '0' && x <= '9')
        char buf[MAXSIZE], *p1, *p2;
        IO() : p1(buf), p2(buf) {}
        inline char gc(){
            if (p1 == p2)
                p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
            return p1 == p2 ? ' ' : *p1++;
        }
        inline bool blank(char ch){
            return ch == ' ' || ch == '
    ' || ch == '
    ' || ch == '	';
        }
        template <class T>
        inline void read(T &x){
            bool sign = 0;
            x = 0;
            char ch = gc();
            for (; !isdigit(ch); ch = gc())
                if (ch == '-')
                    sign = 1;
            for (; isdigit(ch); ch = gc())
                x = x * 10 + (ch - '0');
            if (sign)
                x = -x;
        }
    } io;
    
    struct Q{
        int l, r;
        ll val;
        int id;
    } q[maxm + maxn * maxn], tmp[maxm + maxn * maxn];
    int qcnt;
    ll ans[maxm];
    
    void cmax(ll &x, ll y){
        if (y > x)
            x = y;
    }
    
    struct Bit{
        ll data[maxn];
    
        Bit(){
            fill(data, data + maxn, -inf);
        }
    
        void insert(int pos, ll val){
            for (; pos < maxn; pos += (pos & -pos))
                cmax(data[pos], val);
        }
        void clear(int pos){
            for (; pos < maxn; pos += (pos & -pos))
                data[pos] = -inf;
        }
        ll max(int pos){
            ll ans = -inf;
            for (; pos > 0; pos -= (pos & -pos))
                cmax(ans, data[pos]);
            return ans;
        }
    } bit;
    
    void cdq(int l, int r)
    {
        if (l == r)
            return;
        int mid = (l + r) / 2;
        cdq(l, mid);
        cdq(mid + 1, r);
    
        int id = l;
        vector<int> cl;
        for (int i = l, j = mid + 1; i <= mid || j <= r;)
        {
            if (j > r || i <= mid && q[i].l <= q[j].l)
            {
                tmp[id++] = q[i];
                if (q[i].id == 0)
                {
                    cl.push_back(q[i].r);
                    bit.insert(q[i].r, q[i].val);
                }
                i++;
            }
            else
            {
                tmp[id++] = q[j];
                if (q[j].id)
                    cmax(ans[q[j].id], bit.max(q[j].r));
                j++;
            }
        }
        for (int i = l; i <= r; i++)
            q[i] = tmp[i];
        for (int r : cl)
            bit.clear(r);
    }
    
    int main()
    {
        int n, m;
        io.read(n);
        io.read(m);
        for (int i = 1; i <= n; i++)
        {
            io.read(a[i]);
            sum[i] = sum[i - 1] + a[i];
        }
        for (int i = 1; i <= m; i++)
        {
            io.read(s[i]);
            io.read(e[i]);
            io.read(u[i]);
            q[++qcnt] = {-s[i], e[i], u[i], i};
            ans[i] = -inf;
        }
    
        for (int i = 1; i <= n; i++)
            for (int j = i; j <= n; j++)
                q[++qcnt] = {-i, j, sum[j] - sum[i - 1], 0};
    
        sort(q + 1, q + qcnt + 1, [](Q x, Q y) {
            if (x.val != y.val)
                return x.val < y.val;
            else if (x.l != y.l)
                return x.l < y.l;
            else if (x.r != y.r)
                return x.r < y.r;
            else
                return x.id < y.id;
        });
        cdq(1, qcnt);
        for (int i = 1; i <= m; i++)
        {
            if (ans[i] == -inf)
                printf("NONE
    ");
            else
                printf("%lld
    ", ans[i]);
        }
    
        return 0;
    }
    
  • 相关阅读:
    使用Charles对iPhone进行Http(s)请求拦截(抓包)
    pip 安装 和 卸载 django
    python2.7.5 安装pip
    (Git 学习)Git SSH Key 创建步骤
    git学习四:eclipse使用git提交项目
    我们为什么要使用List和Set(List,Set详解)
    List、Set、Map的区别
    type=hidden
    测试业务分析
    USACO 3.2 kimbits DP
  • 原文地址:https://www.cnblogs.com/intmian/p/14621585.html
Copyright © 2020-2023  润新知