• AT1219 歴史の研究 [回滚莫队]


    歴史の研究

    题目描述见链接 .


    color{red}{正解部分}

    直接使用 莫队, 但是这道题目删除时不好寻找次大值, 考虑 回滚莫队,

    回滚莫队 的处理方式与 莫队 大致是相同的, 具体来说

    对两个相邻的询问区间 [l,r],  [l,r][l',r'], [l, r],

    1. bk_id[l]=bk_id[r]bk\_id[l] = bk\_id[r], 直接 O(N)O(sqrt{N}) 暴力求解 .
    2. bk_id[l]bk_id[l]bk\_id[l'] ot= bk\_id[l], 暴力将左端点和右端点移动到 l+1,ll+1, l .
    3. bk_id[l]=bk_id[l]bk\_id[l'] = bk\_id[l], 暴力处理左端点对答案的贡献, 处理完将左端点归位,
      由于右端点是有序的, 可以直接将右端点从 rr' 移动到 rr, 无需归位,
      每个块移动右端点 O(N)O(N) 次, 复杂度 O(NN)O(Nsqrt{N}) .

    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    typedef long long ll;
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 1e5 + 5;
    
    int N;
    int Q_;
    int Len;
    int bkcnt;
    int A[maxn];
    int B[maxn];
    int llim[maxn];
    int rlim[maxn];
    int bkid[maxn];
    int Tong[maxn];
    int Tong2[maxn];
    
    ll Ans;
    ll res[maxn];
    
    struct Que{ int l, r, id; } que[maxn];
    
    bool cmp(Que a, Que b){ return bkid[a.l]==bkid[b.l]?a.r<b.r:bkid[a.l]<bkid[b.l]; }
    
    void Add(const int &x){ Ans = std::max(Ans, 1ll*B[A[x]]*(++ Tong[A[x]])); }
    
    void Del(const int &x){ Tong[A[x]] --; }
    
    void write(ll x){ if(x > 9) write(x/10); putchar(x%10 + '0'); }
    
    int main(){
            N = read(), Q_ = read();
            for(reg int i = 1; i <= N; i ++) B[i] = A[i] = read();
            std::sort(B+1, B+N+1); Len = std::unique(B+1, B+N+1) - B-1;
            for(reg int i = 1; i <= N; i ++) A[i] = std::lower_bound(B+1, B+Len+1, A[i])-B;
            for(reg int i = 1; i <= Q_; i ++) que[i].l = read(), que[i].r = read(), que[i].id = i;
            int size = sqrt(N);
            for(reg int i = 1; i <= N; i ++){
                    llim[++ bkcnt] = i, rlim[bkcnt] = std::min(N, i+size-1);
                    for(; i <= rlim[bkcnt]; i ++) bkid[i] = bkcnt; i --;
            }
            std::sort(que+1, que+Q_+1, cmp);
            int lt = 1, rt = 0, last = 0;
            for(reg int i = 1; i <= Q_; i ++){
                    if(bkid[que[i].l] == bkid[que[i].r]){ 
                            ll Tmp_1 = 0;
                            for(reg int j = que[i].l; j <= que[i].r; j ++) Tmp_1 = std::max(Tmp_1, 1ll*B[A[j]]*(++ Tong2[A[j]]));
                            for(reg int j = que[i].l; j <= que[i].r; j ++) Tong2[A[j]] --;
                            res[que[i].id] = Tmp_1; continue ;
                    }
                    if(last != bkid[que[i].l]){
                            while(lt < rlim[bkid[que[i].l]]+1) Del(lt ++);
                            while(rt > lt-1) Del(rt --);
                            Ans = 0; last = bkid[que[i].l];
                    }
                    while(rt < que[i].r) Add(++ rt); ll Tmp = Ans;
                    while(lt > que[i].l) Add(-- lt); res[que[i].id] = Ans;
                    while(lt < rlim[bkid[que[i].l]]+1) Del(lt ++); Ans = Tmp;
            }
            for(reg int i = 1; i <= Q_; i ++){ write(res[i]); putchar('
    '); }
            return 0;
    }
    
  • 相关阅读:
    【Devops】 Kubernetes 入门与基础
    【Devops】 DevOps基础与理念
    【Maven】 关于Maven,测试需要掌握的一些知识点
    【转】IntelliJ IDEA中Maven插件无法更新索引
    【Python】 RobotFramework 安装配置与简要操作
    【SpringBoot】 项目中运用的一些技巧,mybatis-plus 自动编译等(持续更新)
    Spring5源码分析(019)——IoC篇之解析alias标签、import标签和beans标签
    Spring5源码分析(018)——IoC篇之解析bean标签:注册解析的BeanDefinition
    Spring5源码分析(017)——IoC篇之解析bean标签:解析默认标签中的自定义标签
    Java学习驿站——Mark
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822430.html
Copyright © 2020-2023  润新知