【笔记篇】莫队算法(二)

这篇笔记介绍了如何在莫队算法中处理查询和修改操作。通过增加时间维度,将查询和修改按块编号及时间排序,确保修改对后续查询的影响被正确处理。文章提到了最优分块大小为n^2/3,并给出了一道例题bzoj2120的解题思路和代码示例,复杂度为O(n^(5/3))。
摘要由CSDN通过智能技术生成

笔记目录:http://blog.csdn.net/enzymii/article/details/77169928

嗯,我们已经能通过莫队处理查询线性结构上的查询了。
但是,这怎么能够呢= =
现在的题里面基本上都要牵扯上修改操作啊。。。
比如动不动就会出一个“把节点x的值修改为y的操作”。。。

而我们知道,莫队是离线算法,要把所有操作都读进来,那么修改操作就会对后面的查询操作造成影响。。
如何消除这种影响呢?
我们可以再加一个维度——时间。
我们对于每一个查询操作,记录一个时间T,表示之前进行过T次修改了。
然后排序的时候,按左端点的块编号为第一关键字,右端点的块编号为第二关键字,时间为第三关键字排序即可。

bool cmp(const query &a,const query &b){
    if(a.l/blk==b.l/blk){
        if(a.r/blk==b.r/blk) return a.ti<b.ti;
        return a.r<b.r;
    }
    return a.l<b.l;
}

对于每一个修改,我们只需要记录每个修改的修改前和修改后的信息,然后像移动L,R一样移动T即可。
定义一个修改的结构体,像这样:

struct modify{
    int pos,pre,now; //这次修改将pos位置从pre改为now
};

我们只需要写一个操作:

void change(int l,int r,int x,int c) //当前区间为[l,r],把x点更改为c
{
    //TODO:这里维护信息
    if(l<=x&&x<=r)
    {
        //维护改动
    }
    //修改该点 比如col[x]=c;
}

然后我们在solve()函数中扫的时候,扫时间的话就

int T=q[i].ti;
while(ti<T) ++ti,change(l,r,t[T].pos,t[T].now); //没改的时候要改成改后的颜色
while(ti>T) change(l,r,t[T].pos,t[T].pre),ti--; //改过了的话要改回改前的颜色

经检验,对于带修改的莫队算法,分块大小分到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值