• 【JZOJ4763】【NOIP2016提高A组模拟9.7】旷野大计算


    题目描述

    这里写图片描述

    输入

    这里写图片描述

    输出

    这里写图片描述

    样例输入

    5 5
    9 8 7 8 9
    1 2
    3 4
    4 4
    1 4
    2 4

    样例输出

    9
    8
    8
    16
    16

    数据范围

    这里写图片描述

    解法

    离线莫队做法

    考虑使用莫队,但由于在删数的时候难以处理,所以考虑“只增莫队”。
    排序询问时以询问左端点所在块编号为第一关键字,右端点编号为第二关键字。
    由于当左端点在同一个块时,移动最多为n^0.5,所以每次询问把左端点直接从块末移动到目标位置,这样就只增不减了。

    在线分块做法

    坑待填

    代码

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const char* fin="aP3.in";
    const char* fout="aP3y.out";
    const int inf=0x7fffffff;
    ll read(){
        char ch=getchar();
        ll x=0;
        while (ch<'0' || ch>'9') ch=getchar();
        while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return x;
    }
    const ll maxn=100007,maxt=maxn*4;
    struct node{
        ll v,id;
    }a[maxn];
    struct qj{
        ll l,r,lk,rk,id;
    }q[maxn];
    ll n,m,i,j,k,ks,l,r,tmp,tmd,tmb;
    ll b[maxn],c[maxn],tong[maxn],la[maxn];
    ll ans1[maxn];
    bool cmp(node a,node b){
        return a.v<b.v;
    }
    bool cmp1(qj a,qj b){
        return a.lk<b.lk || a.lk==b.lk && a.r<b.r;
    }
    ll pos(ll v){
        return (v-1)/ks+1;
    }
    void add(ll v){
        tmb=max(tmb,(++tong[c[v]]+la[c[v]])*b[v]);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for (i=1;i<=n;i++) scanf("%d",&b[i]),a[i].v=b[i],a[i].id=i;
        sort(a+1,a+n+1,cmp);
        j=0;
        ks=int(sqrt(n));
        for (i=1;i<=n;i++) {
            if (a[i].v>a[i-1].v) j++;
            c[a[i].id]=j;
        }
        for (i=1;i<=m;i++){
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].lk=pos(q[i].l);
            q[i].rk=pos(q[i].r);
            q[i].id=i;
        }
        sort(q+1,q+m+1,cmp1);
        l=0;
        r=0;
        tmp=0;
        for (i=1;i<=m;i++){
            if (q[i-1].lk!=q[i].lk){
                memset(la,0,sizeof(la));
                tmd=q[i].lk*ks;
                r=tmd+1;
                tmp=tmb=0;
            }
            l=min(q[i].r+1,tmd+1);
            /*while (l<q[i].l) del(l++);
            while (r>q[i].r) del(r--);*/
            while (l>q[i].l) add(--l);
            while (r<=q[i].r) {
                tmp=max(tmp,(++la[c[r]])*b[r]);
                tmb=max(tmb,(tong[c[r]]+la[c[r]])*b[r]);
                r++;
            }
            for (j=l;j<=q[i].r && j<=tmd;j++) tong[c[j]]--;
            ans1[q[i].id]=tmb;
            tmb=tmp;
        }
        for (i=1;i<=m;i++) printf("%lld
    ",ans1[i]);
        return 0;
    }

    启发

    当莫队删数困难时,考虑“只增莫队”。

  • 相关阅读:
    因为付出,所以喜欢。开发就是这么坑!
    停滞在一个圈子,决定人生的高低![深度文章]
    我不曾忘记的初心-程序员如何看待买房子
    能力要进化-还在技术停滞不前吃老本吗?
    能力要进化-还在技术停滞不前吃老本吗?
    我不曾忘记初心-我们最终都成了自己讨厌的人
    我不曾忘记初心-我们最终都成了自己讨厌的人
    我不曾忘记的初心-冒险努力正是你缺少的!
    我不曾忘记的初心-冒险努力正是你缺少的!
    JS之正则表达式
  • 原文地址:https://www.cnblogs.com/hiweibolu/p/6714902.html
Copyright © 2020-2023  润新知