zoukankan      html  css  js  c++  java
  • bzoj 4241: 历史研究

    传送门

    传说中的回滚莫队。

    按左端点所在块为第一关键字,右端点位置为第2关键字排序。

    分别把左端点在同一个块中的询问一起处理,从这个块的下一个块的第一个元素开始加,因为右端点单调递增,只有加元素的操作。

    然后对于左边的部分,对每个询问暴力加左边的然后考虑答案就好了。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    const int N=1e5+7;
    typedef long long LL;
    using namespace std;
    int n,m,col[N],ls[N],bl[N],kk,sz;
    LL ans[N];
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct node {
        int id,l,r;
        friend bool operator <(const node &A,const node &B) {
            return bl[A.l]<bl[B.l]||(bl[A.l]==bl[B.l]&&A.r<B.r);
        }
    }qs[N];
    
    int cnt[N],lz[N];
    LL ansnow=-1;
    void add(int x,int id) {
        if(lz[x]!=id) lz[x]=id,cnt[x]=1;
        else cnt[x]++;
        ansnow=max(ansnow,(LL)cnt[x]*ls[x]);
    }
    
    int tpc[N],vis[N],tot;
    LL tpadd(int l,int r,int id) {
        tot++;
        LL tpans=ansnow;
        for(int i=l;i<=r;i++) {
            int x=col[i];
            if(vis[x]!=tot) vis[x]=tot,tpc[x]=1;
            else tpc[x]++;
            int y=(lz[x]==id?cnt[x]:0);
            tpans=max(tpans,(LL)(tpc[x]+y)*ls[x]);
        }
        return tpans;
    }
    
    void solve() {
        int nl,nr;
        for(int i=1;i<=m;i++) {
            if(i==1||bl[qs[i].l]!=bl[qs[i-1].l]) //if(bl[qs[i].l]!=bl[qs[i-1].l])
                nl=nr=(bl[qs[i].l]+1)*kk,ansnow=-1;
            while(nr<qs[i].r) add(col[++nr],bl[qs[i].l]);
            ans[qs[i].id]=tpadd(qs[i].l,min(nl,qs[i].r),bl[qs[i].l]);
        }
    } 
    
    int main() {
        read(n); read(m);
        kk=sqrt(n); kk=max(kk,1);
         for(int i=1;i<=n;i++) {
            read(col[i]); 
            ls[i]=col[i];
            bl[i]=(i-1)/kk;
        }
        sort(ls+1,ls+n+1);
        sz=unique(ls+1,ls+n+1)-(ls+1);
        for(int i=1;i<=n;i++) 
            col[i]=lower_bound(ls+1,ls+sz+1,col[i])-ls;
        for(int i=1;i<=m;i++) {
            read(qs[i].l);
            read(qs[i].r);
            qs[i].id=i;
        }
        sort(qs+1,qs+m+1);
        solve();
        for(int i=1;i<=m;i++) printf("%lld
    ",ans[i]);
        return 0;
    }
    /*
    5 5
    9 8 7 8 9
    1 2
    3 4
    4 4
    1 4
    2 4
    */
    View Code
  • 相关阅读:
    UIScrollView控件介绍
    xib的简单使用
    使用xib开发界面
    浅析IOS中的AutoLayout
    关于字典转模型的个人理解
    Linux开发基础环境配置
    深度学习相关环境的配置
    蓝牙协议分析(2)_协议架构
    蓝牙协议分析(1)_基本概念
    10项目实战-交易数据异常检测
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8390409.html
Copyright © 2011-2022 走看看