zoukankan      html  css  js  c++  java
  • SP1557 GSS2

    一开始看不懂题解,看懂了题解之后觉得还是挺妙的。

    好多题解里都提到了HH的项链,但是我觉得关系并不大啊……

    先把所有询问离线下来按照右端点排序,按照询问的要求一个一个加入数字,怎么加入数字,我们设计一颗特别的线段树:

    假设当前我们在$[1, r]$中已经加完了数字,那么线段树的叶子结点$l$表示$sum_{i = l}^{r}a_i$,非叶子结点在左右儿子之间取个最大值就好了,然后我们发现这样子答案就是询问区间中曾经出现过的数的最大的一个值,我们只要把这个最大值顺便保留计算一下就好了。

    考虑一下怎么添加数,对于一个下标$i$,只要在$[pre_i + 1, i]$中区间加$a_i$即可($pre_i$表示前一个$a_i$出现的位置)。

    用两个标记维护当前最大值和历史最大值,实现起来有一些细节。

    时间复杂度$O(nlogn)$。

    Code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    
    const int N = 1e5 + 5;
    const int Fix = 1e5;
    
    int n, qn, a[N], head[N << 1], pre[N];
    
    struct Querys {
        int l, r, id;
        ll res;
    
        friend bool operator < (const Querys &x, const Querys &y) {
            return x.r < y.r;
        }
    
    } q[N];
    
    inline void read(int &X) {
        X = 0; char ch = 0; int op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline ll max(ll x, ll y) {
        return x > y ? x : y;
    }
    
    template <typename T>
    inline void chkMax(T &x, T y) {
        if(y > x) x = y;
    }
    
    namespace SegT {
        struct Node {
            ll mx, tag, his, htag;
    
            inline Node (ll nowMx = 0LL, ll nowTag = 0LL, ll nowHis = 0LL, ll nowHtag = 0LL) {
                mx = nowMx, tag = nowTag, his = nowHis, htag = nowHtag;
            }
    
        } s[N << 2];
    
        #define lc p << 1
        #define rc p << 1 | 1
        #define mid ((l + r) >> 1)
        #define mx(p) s[p].mx
        #define tag(p) s[p].tag
        #define his(p) s[p].his
        #define htag(p) s[p].htag
    
        inline void up(int p) {
            mx(p) = max(mx(lc), mx(rc));
            his(p) = max(his(lc), his(rc));
        }
    
        inline void down(int p) {
            chkMax(his(lc), mx(lc) + htag(p));
            chkMax(his(rc), mx(rc) + htag(p));
            mx(lc) += tag(p), mx(rc) += tag(p);
            chkMax(htag(lc), tag(lc) + htag(p));
            chkMax(htag(rc), tag(rc) + htag(p));
            tag(lc) += tag(p), tag(rc) += tag(p);
            tag(p) = htag(p) = 0;
        }
    
        void modify(int p, int l, int r, int x, int y, ll v) {
            if(x <= l && y >= r) {
                mx(p) += v;
                chkMax(his(p), mx(p));
                tag(p) += v;
                chkMax(htag(p), tag(p));
                return;
            }
    
            down(p);
            if(x <= mid) modify(lc, l, mid, x, y, v);
            if(y > mid) modify(rc, mid + 1, r, x, y, v);
            up(p);
        }
    
        ll query(int p, int l, int r, int x, int y) {
            if(x <= l && y >= r) return s[p].his;
            down(p);
    
            ll res = 0;
            if(x <= mid) chkMax(res, query(lc, l, mid, x, y));
            if(y > mid) chkMax(res, query(rc, mid + 1, r, x, y));
            return res;
        }
    
    } using namespace SegT;
    
    int main() {
        read(n);
        for(int i = 1; i <= n; i++) {
            read(a[i]);
            pre[i] = head[a[i] + Fix];
            head[a[i] + Fix] = i;
        }
    
        read(qn);
        for(int i = 1; i <= qn; i++) {
            read(q[i].l), read(q[i].r);
            q[i].id = i, q[i].res = 0LL;
        }
    
        sort(q + 1, q + 1 + qn);
        for(int j = 1, i = 1; i <= qn; i++) {
            for(; j <= q[i].r && j <= n; j++) 
                modify(1, 1, n, pre[j] + 1, j, 1LL * a[j]);
            ll now = query(1, 1, n, q[i].l, q[i].r);
            q[q[i].id].res = now;
        }
    
        for(int i = 1; i <= qn; i++)
            printf("%lld
    ", q[i].res);
        
        return 0;
    }
    View Code
  • 相关阅读:
    本地搭建Nginx服务器启动web项目
    BZOJ 1815: [Shoi2006]color 有色图(Polya定理)
    即将退役选手最后的挣扎
    类欧几里得算法
    UOJ#449. 【集训队作业2018】喂鸽子(期望dp)
    Luogu P3600 随机数生成器(期望+dp)
    毒题选讲选做
    UOJ#310.【UNR #2】黎明前的巧克力(FWT)
    DZY Loves Math 系列详细题解
    项目中经常遇到的跨域请求的几种方法
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9829639.html
Copyright © 2011-2022 走看看