[BZOJ4241]历史研究:回滚莫队

同样是回滚莫队怎么差的怎么多?

本蒟蒻的代码(T的飞起):

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
struct ios{
    inline char read(){
        static const int IN_LEN=1<<18|1;
        static char buf[IN_LEN],*s,*t;
        return (s==t)&&(t=(s=buf)+fread(buf,1,IN_LEN,stdin)),s==t?-1:*s++;
    }
    template <typename _Tp> inline ios & operator >> (_Tp&x){
        static char c11,boo;
        for(c11=read(),boo=0;!isdigit(c11);c11=read()){
            if(c11==-1)return *this;
            boo|=c11=='-';
        }
        for(x=0;isdigit(c11);c11=read())x=x*10+(c11^'0');
        boo&&(x=-x);
        return *this;
    }
}io;
const int SIZE=100005;
int n,m,K;
int a[SIZE],b[SIZE],f[SIZE],tim[SIZE],tim2[SIZE];
struct Ask{
    int l,r,lk,no;
    LL ans;
}sk[SIZE];
bool cmp(Ask x,Ask y){
    if(x.lk<y.lk) return 1;
    if(x.lk>y.lk) return 0;
    return x.r<y.r;
}
bool cmp2(Ask x,Ask y){
    return x.no<y.no;
}
int main(){
    io>>n>>m;
    for(int i=1;i<=n;i++){
        io>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+n+1);
    int siz=unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=n;i++){
        int temp=a[i];
        a[i]=lower_bound(b+1,b+siz+1,a[i])-b;
        f[a[i]]=temp;
    }
    K=sqrt(n);
    for(int i=1;i<=m;i++){
        io>>sk[i].l>>sk[i].r;
        sk[i].lk=(sk[i].l-1)/K+1;
        sk[i].no=i;
    }
    sort(sk+1,sk+m+1,cmp);
    register int h=K*sk[1].lk+1,t=sk[1].r,p=1;
    LL ans=0,rez=0;bool flag=0;
    while(p<=m){
        if(flag==0){
            memset(tim,0,sizeof tim);
            for(int i=h;i<=t;i++){
                tim[a[i]]++;
                ans=max(ans,(LL)tim[a[i]]*f[a[i]]);
            }
            flag=1;
        }
        else{
            while(t<sk[p].r){
                t++;
                if(t>=h){
                    tim[a[t]]++;
                    ans=max(ans,(LL)tim[a[t]]*f[a[t]]);
                }
            }
        }
        memset(tim2,0,sizeof tim2);
        rez=ans;
        for(register int i=min(h-1,sk[p].r);i>=sk[p].l;i--){
            tim2[a[i]]++;
            rez=max(rez,(LL)(tim[a[i]]+tim2[a[i]])*f[a[i]]);
        }
        sk[p].ans=rez;
        if(sk[p+1].lk==sk[p].lk){
            p++;
            continue;
        }
        else h=K*sk[++p].lk+1,t=sk[p].r,ans=0,flag=0;
    }
    sort(sk+1,sk+m+1,cmp2);
    for(int i=1;i<=m;i++)
        printf("%lld\n",sk[i].ans);
    return 0;
}

yashem66dalao的代码:https://blog.csdn.net/qq_33330876/article/details/73522230

/**************************************************************
    Problem: 4241
    User: CHN
    Language: C++
    Result: Accepted
    Time:9968 ms
    Memory:5592 kb
****************************************************************/

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

inline int read() {
    register int val=0; char ch;
    while(~(ch=getchar()) && (ch<'0' || ch>'9')); val=ch-'0';
    while(~(ch=getchar()) && (ch>='0' && ch<='9')) val=(val<<1)+(val<<3)+ch-'0';
    return val;
}

const int maxn=int(1e5)+111;
int n,m;
int a[maxn], b[maxn], v[maxn];
int siz, num, bel[maxn];
long long ans[maxn];

struct Q {
    int l,r,id;
    bool operator < (const Q &b) const {
        return bel[l]==bel[b.l]?r<b.r:bel[l]<bel[b.l];
    }
}q[maxn];

void Read() {
    register int i;
    n=read(), m=read();
    for(i=1;i<=n;++i)
        v[i]=a[i]=read();

    sort(v+1,v+1+n);
    int nn=unique(v+1,v+1+n)-(v+1);
    for(i=1;i<=n;++i)
        b[i]=lower_bound(v+1,v+1+nn,a[i])-v;

    for(i=1;i<=m;++i) {
        q[i].l=read(), q[i].r=read();
        q[i].id=i;
    }
    while(siz*siz<n) ++siz;
    for(i=1;i<=n;++i)
        bel[i]=(i-1)/siz+1, num=max(num,bel[i]);
    sort(q+1,q+1+m);
    return;
}

long long tmp=0;
int cnt[maxn];

void Add(int id) {
    ++cnt[b[id]];
    tmp=max(tmp,1ll*cnt[b[id]]*a[id]);
}
void Del(int id) {
    --cnt[b[id]];
}

long long small(int l,int r) {
    static int cnt2[maxn];
    long long res=0;
    register int i;
    for(i=l;i<=r;++i)
        cnt2[b[i]]=0;
    for(i=l;i<=r;++i) {
        ++cnt2[b[i]];
        res=max(res,1ll*cnt2[b[i]]*a[i]);
    }
    return res;
}

int Mo(int pos,int id) {
    int L=min(id*siz,n);
    register int i=pos,j, ql=L+1, qr=ql-1;
    for(j=1;j<=n;++j) cnt[j]=0;
    tmp=0;
    for(;bel[q[i].l]==id;++i) {
        if(bel[q[i].l]==bel[q[i].r]) {
            ans[q[i].id]=small(q[i].l,q[i].r);
            continue;
        }
        while(qr<q[i].r) Add(++qr);
        long long cur=tmp;
        while(ql>q[i].l) Add(--ql);
        ans[q[i].id]=tmp;
        while(ql<L+1) Del(ql++);
        tmp=cur;
    }
    return i;
}

void Solve() {
    register int i,pos=1;
    for(i=1;i<=num;++i)
        pos=Mo(pos,i);
    return;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
#endif
    Read();
    Solve();

    for(int i=1;i<=m;++i)
        printf("%lld\n",ans[i]);

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9463850.html