BZOJ.2453.维护队列([模板]带修改莫队)

题目链接

带修改莫队: 普通莫队的扩展,依旧从[l,r,t]怎么转移到[l+1,r,t],[l,r+1,t],[l,r,t+1]去考虑
对于当前所在的区间维护一个vis[l~r]=1,在修改值时根据是否在当前区间内修改即可。
块大小取\(O(n^{\frac{2}{3}})\),排序依次按左端点所在块、右端点所在块、修改次数(时间)
复杂度为\(O(n^{\frac{5}{3}})\) (证明在这)

#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=1e4+5;

int n,m,size,bel[N],A[N],Now,tm[N*100],las[N],Ans[N];
bool vis[N*100];
struct Ask
{
    int l,r,id,t;
    Ask() {}
    Ask(int l,int r,int id,int t): l(l),r(r),id(id),t(t) {} ;
    bool operator <(const Ask &a)const
    {
        if(bel[l]==bel[a.l]) return bel[r]==bel[a.r]?t<a.t:r<a.r;
        return l<a.l;
    }
}qa[N];
struct Modify
{
    int pos,val,bef;
    Modify() {}
    Modify(int p,int v,int b): pos(p),val(v),bef(b) {} ;
}qm[1005];

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
void Calc(int p)
{
    if(vis[p])
        if(!--tm[A[p]]) --Now;
        else ;
    else if(++tm[A[p]]==1) ++Now;
    vis[p]^=1;
}
void Change(int p,int v)
{
    if(vis[p]) Calc(p), A[p]=v, Calc(p);//(当前位置)在当前访问区间中,先将原先值删掉,再修改、添加
    else A[p]=v;//不在访问区间中,直接改掉即可
}

int main()
{
    n=read(),m=read(),size=pow(n,0.667);
    for(int i=1; i<=n; ++i) bel[i]=(i-1)/size+1, las[i]=A[i]=read();
    int na=0,nm=0; char opt[3];
    for(int a,b,i=1; i<=m; ++i)
    {
        scanf("%s",opt),a=read(),b=read();
        if(opt[0]=='Q') qa[++na]=Ask(a,b,na,nm);
        else qm[++nm]=Modify(a,b,las[a]),las[a]=b;
    }
    std::sort(qa+1,qa+1+na);
    for(int l=1,r=0,t=0,i=1; i<=na; ++i)
    {
        while(t<qa[i].t) ++t,Change(qm[t].pos,qm[t].val);
        while(t>qa[i].t) Change(qm[t].pos,qm[t].bef),--t;
        while(l<qa[i].l) Calc(l++);//不能直接代入A[p] vis[]是某位置的标记
        while(l>qa[i].l) Calc(--l);
        while(r<qa[i].r) Calc(++r);
        while(r>qa[i].r) Calc(r--);
        Ans[qa[i].id]=Now;
    }
    for(int i=1; i<=na; ++i) printf("%d\n",Ans[i]);

    return 0;
}

原文地址:https://www.cnblogs.com/SovietPower/p/8456199.html

时间: 2024-08-13 13:43:03

BZOJ.2453.维护队列([模板]带修改莫队)的相关文章

[bzoj2453]维护队列_带修改莫队

维护队列 bzoj-2453 题目大意:给定一个n个数序列,支持查询区间数的种类数,单点修改.不强制在线. 注释:$1\le n,m\le 10^5$. 想法: 带修改莫队裸题. 如果没有修改操作的话,我们就正常按照莫队一样左右移动区间即可. 有了修改操作的话,我们把块变成$n^{\frac{2}{3}}$,关键字变成:左端点所在块.右端点所在块和时间戳. 然后暴力就行了. Code: #include <iostream> #include <cstdio> #include &

bzoj 3052: [wc2013]糖果公园 带修改莫队

3052: [wc2013]糖果公园 Time Limit: 250 Sec  Memory Limit: 512 MBSubmit: 506  Solved: 189[Submit][Status] Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 HINT 本来这道题想到了莫队算法,但是看到带修改就直接放弃了.结果看题解才发现带修改居然也能用莫队!!!之所以可以这样用,是因为修改的时间复

BZOJ 2120 数颜色(带修改莫队)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2120 [题目大意] 给出一颜色序列,每次可以修改一个位置的颜色或者询问一个区间不同颜色的数目. [题解] 我们按照最近一次修改对查询操作进行时间标号,在莫队排序的时候引入时间作为第三维, 对于每个修改操作,我们记录修改之前的颜色和修改之后的颜色, 对于两个相邻两个查询,我们将其之间时间差距的修改操作进行记录或者撤销之后查询即可. [代码] #include <cstdio> #in

[BZOJ 4129]Haruna’s Breakfast(树上带修改莫队)

Description Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了一棵 树上,每个结点都有一样食材,Shimakaze要考验一下她. 每个食材都有一个美味度,Shimakaze会进行两种操作: 1.修改某个结点的食材的美味度. 2.对于某条链,询问这条链的美味度集合中,最小的未出现的自然数是多少.即mex值. 请你帮帮Haruna吧. Solution 树上带修改莫队 统计答案的时候也分块查询,找到第一个没满的块开始一个一个找 #include<i

【Luogu】P1903数颜色(带修改莫队)

题目链接 带修改莫队模板. 加一个变量记录现在是第几次修改,看看当前枚举的询问是第几次修改,改少了就改过去,改多了就改回来. 话说我栈用成队列了能过样例?!!!! 从此深信一句话:样例是出题人精心设计的,绞尽脑汁才设计出一个能让错误代码通过的数据qwqqqqq #include<cstdio> #include<cstdlib> #include<cctype> #include<algorithm> #include<cstring> #inc

F. Machine Learning (带修改莫队)

https://codeforces.com/contest/940/problem/F 题意  给出n个数字,q个询问: 每次询问有两种类型,一种是询问区间,一种是单体修改: 询问区间是询问区间内最小的没用到的大于0的整数: 比如我有一串数字是 1 1 2 2 2 3    那么有两个1 三个2,一个3   出现次数分别有 两 三 一,  那么次数最小的没在区间内出现的是4: 对于这道题,除带修改莫队的模板之外,我们多加两个数组 vis cnt vis数组用来记录某个数出现的频率,cnt用来记

[UOJ #58][WC2013]糖果公园(树上带修改莫队)

Description Solution 树上带修改莫队…!VFK的题解写得很清楚啦 (我的程序为什么跑得这么慢…交的时候总有一种自己在卡测评的感觉…) #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define MAXN 100005 typedef long l

BZOJ2120数颜色(带修改莫队)

2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 7384  Solved: 2998[Submit][Status][Discuss] Description 墨 墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要

bzoj 2453 : 维护队列 带修莫队

2453: 维护队列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 952  Solved: 432[Submit][Status][Discuss] Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色.但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你