zoukankan      html  css  js  c++  java
  • 带修改莫队浅谈

    二逼平衡树写得我兹娃乱叫之时,学习了清流的算法——莫队。这次是莫队的进阶版本,资瓷单点修改操作。

    原来需要的是两个关键字,而现在多了一维时间。

    第一个关键字L表示查询左端点l所在的块的编号,第二个关键字R表示查询右端点r所在块的编号(并不是右端点的值了,因为还有第三维),第三个关键字为时间t。

    在这里我们是对修改操作维护的时间轴,之后在查询操作中查找离此次查询操作最近的一次修改操作的时间(请仔细思考)

    如果现在的时间比需要的时间大,那么我们让时间倒流,改回原值,剩下的就交给普通莫队了。

    我们来对时间复杂度进行证明。

    对于一块到底是多少使得时间复杂度最优的问题,我们来分析一下。

    以下是luogu题解中的内容对于t轴的移动可以保存每次修改,如果修改在(l,r)间则更新

    分块方法可以参照原版莫队,先将l分块,再讲r分块,同一块的按t排序

    块大小为 可以达到最快的理论复杂度 ,证明如下

    设分块大小为a,莫队算法时间复杂度主要为t轴移动,同r块l,r移动,l块间的r移动三部分

    t轴移动的复杂度为 ,同r块l,r移动复杂度为 ,l块间的r移动复杂度为

    三个函数max的最小值当a为 取得,为

    综上所述,一块大小为√n3

    我们直接用STL解决

    size=pow(n,0.67);
    

     HH的项链的进阶版,多了个单点修改

    P1903 [国家集训队]数颜色 / 维护队列

    // luogu-judger-enable-o2
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define N 50010
    int size;
    int n,Q;
    struct Query
    {
        int blobx,bloby,x,y,daan,id,pre;
    }query[N];
    struct Change
    {
        int pos,color;
    }change[N];
    int a[N];
    int col[N];
    int sum[1000100];
    int ans;
    char q[3];
    int idx,idx2;
    int x,y;
    bool cmp(const Query &a,const Query &b)
    {
        if(a.blobx!=b.blobx)
            return a.blobx<b.blobx;
        if(a.bloby!=b.bloby)
            return a.bloby<b.bloby;
        return a.id<b.id;
    }
    bool cmp2(const Query &a,const Query &b)
    {
        return a.id<b.id;
    }
    int calc(int x)
    {
        if(x%size==0)
            return x/size;
        else
            return x/size+1;
    }
    void del(int x)
    {
        if(--sum[a[x]]==0)
            ans--;
    }
    void add(int x)
    {
        if(++sum[a[x]]==1)
            ans++;
    }
    void go(int now,int i)
    {
        if(change[now].pos>=query[i].x&&change[now].pos<=query[i].y)
        {
            if(--sum[a[change[now].pos]]==0)
                ans--;
            if(++sum[change[now].color]==1)
                ans++;
        }
        swap(a[change[now].pos],change[now].color);
    }
    int main()
    {
        scanf("%d%d",&n,&Q);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        size=pow(n,0.67);
        for(int i=1;i<=Q;i++)
        {
            scanf("%s",q);
            if(q[0]=='Q')
            {
                scanf("%d%d",&x,&y);
                query[++idx].x=x;
                query[idx].y=y;
                query[idx].blobx=calc(query[idx].x);
                query[idx].bloby=calc(query[idx].y);
                query[idx].id=idx;
                query[idx].pre=idx2;
            }
            else
            {
                scanf("%d%d",&x,&y);
                change[++idx2].pos=x;
                change[idx2].color=y;
            }
        }
        sort(query+1,query+idx+1,cmp);
        int l=1,r=0,tim=0;
        for(int i=1;i<=idx;i++)
        {
            while(l<query[i].x)
                del(l++);
            while(l>query[i].x)
                add(--l);
            while(r<query[i].y)
                add(++r);
            while(r>query[i].y)
                del(r--);
            while(tim<query[i].pre)
                go(++tim,i);
            while(tim>query[i].pre)
                go(tim--,i);
            query[i].daan=ans;
        }
        sort(query+1,query+idx+1,cmp2);
        for(int i=1;i<=idx;i++)
            printf("%d
    ",query[i].daan);
    }
    
  • 相关阅读:
    Python的__init__.py用法
    Python中文
    使用apache进行域名绑定
    Storm入门之第二章
    Storm入门之第一章
    【RabbitMQ+Python入门经典】兔子和兔子窝 笔记
    RabbitMQ之Topics(多规则路由)
    RabbitMQ之比较好的资料
    RabbitMQ之路由
    RabbitMQ之发布订阅
  • 原文地址:https://www.cnblogs.com/342zhuyongqi/p/10142592.html
Copyright © 2011-2022 走看看