因为今天考到莫队裸题了嘤嘤嘤...而我这样的蒟蒻肯定不会这样的高端算法啊QAQ。于是暴力水了40分qwq。

正如上文所说,我实在太菜了,于是学习莫队也只是学习了最简单的不带修普通莫队,如果我能苟到省选那就再继续学啦。

掏心推荐:深度好文,浅谈根号算法--分块 By new2zy


一、莫队的思想及处理的问题

红太阳金涛说的吼啊:莫队本质上就是一种优化的暴力。

所以莫队到底能适用什么样的问题呢?基本上所有的离线区间查询问题(暂时不带修)都能用莫队算法苟过233...所以莫队算法还真是强啊%%。

离线区间查询?意思就是在说,我们先把所有需要进行区间查询的信息保存下来,然后根据一定的方法规则对这些区间查询信息进行排序。(这里我们一会再说qwq)

排序之后,我们就可以用两个指针$posl$和$posr$(可能有些像cf上的two pointer?不太确定qwq),不断调整他们的位置直到与查询区间精确重合并维护$[posl,posr]$区间内的信息,来处理询问。

而莫队算法也是需要把序列分成很多块的(分块算法的好基友),一般是分成$sqrt(n)$块,当然也有其他玄学分块方式。

而莫队的时间复杂度一般是$O(n*sqrt(n))$的,具体分析过程我就光速逃了qwq。(不会qwq)

另外,刚才我们留了个锅,就是关于将询问排序的方法:

  • 一般的排序是这样的:先按左端点所在块排,再按右端点位置排。但是这个排序有时比较弱,卡不过毒瘤们的精心构造。
  • 于是产生了更加优秀的一种排序:按奇偶块排序。这也是比较通用的。如果区间左端点所在块不同,那么就直接按左端点从小到大排;如果相同,鸡块奇块按右端点从小到大排,偶块按右端点从大到小排。
bool cmp(query a,query b)
{
return (a.l/block)^(b.l/block) ? a.l<b.l : (((a.l/block)&) ? a.r<b.r : a.r>b.r);
}

至于证明...我太菜了放过我吧


二、丢几道例题跑

其实..莫队的核心代码除排序的cmp外只有四行...

        int l=ask[i].l,r=ask[i].r;
while(posl<l) remove(posl++); //当前区间左端点在查询区间的左边 想要向右移 但是因为当前的posl不在查询区间中所以把它对答案的贡献去除。
while(posr>r) remove(posr--); //其他同理233
while(posl>l) add(--posl);
while(posr<r) add(++posr);
ans[ask[i].id]=noww;

什么这不是六行嘛

例题1 小B的询问

莫队裸题。左右指针移动实际上就是数字的增减,我们改变了桶的大小(计数数组大小后),考虑如果一个数字p减小,那么它对答案的贡献就会少。少了多少呢?考虑完全平方公式。设$x=cnt[p]$。

$(x+1)^2$------->>>>>>$x^2$

$x^2+2*x+1$------->>>>>>$x^2$

显然少了$2*x+1$,那么增加同理。之后就是套裸的莫队了。

#include<cstdio>
#include<algorithm>
#include<cmath> using namespace std; int n,m,k,block,posl=,posr,noww;
int seq[],ans[],sum[];
struct query{
int l,r,id,in;
}ask[]; bool cmp(query a,query b)
{
return (a.l/block)^(b.l/block) ? a.l<b.l : (((a.l/block)&) ? a.r<b.r : a.r>b.r);
} void remove(int x)
{
sum[seq[x]]--;
noww-=*sum[seq[x]]+;
} void add(int x)
{
sum[seq[x]]++;
noww+=*sum[seq[x]]-;
} int main()
{
scanf("%d%d%d",&n,&m,&k);
block=sqrt(n);
for(int i=;i<=n;i++) scanf("%d",&seq[i]);
for(int i=;i<=m;i++)
{
scanf("%d%d",&ask[i].l,&ask[i].r);
ask[i].id=i;
ask[i].in=ask[i].l/block;
}
sort(ask+,ask++m,cmp);
for(int i=;i<=m;i++)
{
int l=ask[i].l,r=ask[i].r;
while(posl<l) remove(posl++);
while(posr>r) remove(posr--);
while(posl>l) add(--posl);
while(posr<r) add(++posr);
ans[ask[i].id]=noww;
}
for(int i=;i<=m;i++) printf("%d\n",ans[i]);
return ;
}

例题2

也是一道裸的不带修莫队。因为每个数范围在1e9内,所以先离散化一下,然后上裸的莫队。但是正睿神机(?)竟然卡unique......嘤。

#include<cstdio>
#include<algorithm>
#include<cmath> using namespace std; int n,Q,block,m,posl=,posr,noww;
int seq[],b[],tong[],ans[];
struct query{
int l,r,id,in;
}ask[]; void re(int &x)
{
x=;
char ch=getchar();
bool flag=false;
while(ch<''||ch>'') flag|=(ch=='-'),ch=getchar();
while(ch>=''&&ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
x=flag ? -x : x;
} bool cmp(query a,query b)
{
// return (a.l/block)^(b.l/block) ? a.l<b.l : (((a.l/block)&1) ? a.r<b.r : a.r>b.r);
return a.in==b.in?(a.in&)?a.r<b.r:a.r>b.r:a.in<b.in;
} void remove(int x)
{
tong[seq[x]]--;
if(tong[seq[x]]==) noww++;
if(tong[seq[x]]==) noww--;
} void add(int x)
{
tong[seq[x]]++;
if(tong[seq[x]]==) noww++;
if(tong[seq[x]]==) noww--;
} int main()
{
re(n);re(Q);
for(int i=;i<=n;i++) re(seq[i]),b[i]=seq[i];
sort(b+,b++n);
// m=unique(b+1,b+1+n)-(b+1);
for(int i=;i<=m;i++) seq[i]=lower_bound(b+,b++m,seq[i])-b;
block=sqrt(n);
for(int i=;i<=Q;i++)
{
re(ask[i].l);re(ask[i].r);
ask[i].id=i;ask[i].in=ask[i].l/block;
}
sort(ask+,ask++Q,cmp);
for(int i=;i<=Q;i++)
{
int l=ask[i].l,r=ask[i].r;
while(posl<l) remove(posl++);
while(posr>r) remove(posr--);
while(posl>l) add(--posl);
while(posr<r) add(++posr);
ans[ask[i].id]=noww;
}
for(int i=;i<=Q;i++) printf("%d\n",ans[i]);
return ;
}

更强的莫队算法,以后再见啦:)(如果我联赛后还能继续苟233)

莫队初探(不带修/例题极少)By cellur925的更多相关文章

  1. 【树上莫队】【带修莫队】【权值分块】bzoj4129 Haruna’s Breakfast

    #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using ...

  2. 【树上莫队】【带修莫队】bzoj3052 [wc2013]糖果公园

    #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using ...

  3. 【树上莫队】【带修莫队】【权值分块】bzoj1146 [CTSC2008]网络管理Network

    #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using ...

  4. 「洛谷1903」「BZOJ2120」「国家集训队」数颜色【带修莫队,树套树】

    题目链接 [BZOJ传送门] [洛谷传送门] 题目大意 单点修改,区间查询有多少种数字. 解法1--树套树 可以直接暴力树套树,我比较懒,不想写. 稍微口胡一下,可以直接来一个树状数组套主席树,也就是 ...

  5. 【BZOJ2120】数颜色(带修莫队)

    点此看题面 大致题意:告诉你\(n\)只蜡笔的颜色,有两种操作:第一种操作将第\(x\)只蜡笔颜色改成\(y\),第二种操作询问区间\([l,r]\)内有多少种颜色的蜡笔. 考虑普通莫队 这题目第一眼 ...

  6. P5168 xtq玩魔塔 [克鲁斯卡尔重构树+带修莫队]

    P5168 xtq玩魔塔 又是码农题- 利用克鲁斯卡尔重构树的性质 我们就可以得出 \(dep\) 值小的,肯定比 \(dep\) 大的值要优. 于是第二问就可以直接 LCA 求出来了- 至于第三问, ...

  7. 【洛谷】1494:[国家集训队]小Z的袜子【莫队】

    P1494 [国家集训队]小Z的袜子 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… ...

  8. BZOJ 4129 Haruna’s Breakfast (分块 + 带修莫队)

    4129: Haruna’s Breakfast Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 835  Solved: 409[Submit][St ...

  9. 【bzoj4129】Haruna’s Breakfast 带修改树上莫队+分块

    题目描述 给出一棵树,点有点权.支持两种操作:修改一个点的点权,查询链上mex. 输入 第一行包括两个整数n,m,代表树上的结点数(标号为1~n)和操作数.第二行包括n个整数a1...an,代表每个结 ...

随机推荐

  1. 九度OJ #1437 To Fill or Not to Fil

    题目描写叙述: With highways available, driving a car from Hangzhou to any other city is easy. But since th ...

  2. 多线程网页爬虫 python 实现(二)

    #!/usr/bin/env python #coding=utf-8 import threading import urllib import re import time cur=0 last= ...

  3. java开始到熟悉60

    本次主题:多维数组 1,多维数组的初始话有三种:默认初始化.静态初始化.动态初始化. 这里只讲解静态初始化: 这里以二位数组为例,实际应用中,一维用得最多,二维次之,三维以及三维以上几乎很少使用,而且 ...

  4. php操作xml的方法

    xml源文件 <?xml version="1.0 encoding="UTF-8"?> <humans> <zhangying> & ...

  5. PandoraBox 支持3G无线上网卡(电信卡3G卡)(三)

    笔者采用的是华为EC122无线上网卡 一:编辑/etc/modules.d/60-usb-serial usbserial vendor=0x12d1   product=0x1505 二:编辑/et ...

  6. HDOJ_ How can I read input data until the end of file ?

    Language C C++ Pascal To read numbers int n;while(scanf("%d", &n) != EOF){ ...} int n; ...

  7. bzoj3957: [WF2011]To Add or to Multiply

    gay队牛逼! 我们可以强行拆一下柿子,最终得到的值会是m^k*x+m^k*u(k)*a+m^k-1*u(k-1)*a……m^0*u(0)*a 其中u表示后面有i个m的a有多少个 答案就是k+∑u 枚 ...

  8. Pyhton:List build-in function

    列表是Python中的可迭代对象之一,在讲列表的内建函数之前我们可以自己在IDE上看看都有那些内建函数,我们可以在pycharm中使用代码及其运行结果如下: print(dir(list)) ['__ ...

  9. hadoop异常:Be Replicated to 0 nodes, instead of 1

    Hadoop 坑爹的Be Replicated to 0 nodes, instead of 1 异常 博客分类: Java 编程 HadoopITeyeJSP算法Apache  有段时间不写博客了, ...

  10. 百度地图API--信息窗口

    信息窗口 -----纯文本信息窗口 为了更方便的提示用户,在地图的指定的地方添加文本信息的窗口,给用户直观展示信息,下面是如何添加一个纯文本的信息窗口. 下面是添加一个文本窗口: /* * 添加纯文本 ...