莫队算法

发明者:队爷莫涛
基于分块的一种暴力算法, 复杂度最慢可以被卡到\(n^2\)正常情况下的复杂度大约在\(O(n\sqrt{n})\)左右分块的大小对复杂的影响很大其中最优分块的大小为\(\dfrac {s}{\sqrt{m}}\) 最优复杂度为\(O(n\sqrt{m})\)

证明

用处:维护区间信息

具体做法

  • 对求的\(l-r\)区间进行排序,根据\(l\)和\(r\)所在块的位置,进行排序
  • 对排序后的\(l-r\)的区间进行维护,观察维护的数据具有什么特点

注意:

  • 4个\(while\)循环不能乱,根据先后关系进行确定(24中全排列,6中正确)
  • 莫队比较卡常,注意写小常数

    例题

    这个就是概率问题
  • 例子1 eg:3 3 4 5 6 4

    \(ans = \dfrac{2}{6} \times \dfrac{1}{5} + \dfrac{2}{6} \times \dfrac{1}{5} = \dfrac{2}{15}\)

    莫队的过程就是
l = 1 ,r = 0 ,son = 0
l = 1 ,r = 1 ,son = 0
l = 1 ,r = 2 ,son = 2 * ( 2 - 1 ) / 2
l = 1 ,r = 3 ,son = 2 * ( 2 - 1 ) / 2
l = 1 ,r = 4 ,son = 2 * ( 2 - 1 ) / 2
l = 1 ,r = 5 ,son = 2 * ( 2 - 1 ) / 2
l = 1 ,r = 6 ,son = 2 * ( 2 - 1 ) / 2 + 2 * (2 - 1) / 2
mo = 6 * (6 - 1) / 2
  • 例子1 eg: 3 3 3 4 5 6 4
l = 1 ,r = 0 ,son = 0
l = 1 ,r = 1 ,son = 2 * ( 2 - 1 ) / 2
l = 1 ,r = 2 ,son = 3 * ( 3 - 1 ) / 2
l = 1 ,r = 3 ,son = 3 * ( 3 - 1 ) / 2
l = 1 ,r = 4 ,son = 3 * ( 3 - 1 ) / 2
l = 1 ,r = 5 ,son = 3 * ( 3 - 1 ) / 2
l = 1 ,r = 6 ,son = 3 * ( 3 - 1 ) / 2 + 2 * (2 - 1) / 2
mo = 7 * (7 - 1) / 2

过程中先删去前一个的贡献再加上后一个的贡献

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#define orz puts("LKP AK IOI")
#define ll long long
using namespace std;
const int N = 5e4+100;
int read(){
int s = 0 ,f = 1; char ch = getchar();
while(ch < '0'||ch > '9'){if(ch == '-') f = -1 ; ch = getchar();}
while(ch >= '0'&&ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
return s * f;
}
ll sqrtn , l = -1, r = 0, ans;
ll son[N], mo[N];
struct node {
int l, r, id;
bool operator < (const node &x) const {
if( l / sqrtn != x.l / sqrtn) return l < x.l;
if((l/sqrtn) & 1) return r < x.r;
return r > x.r;
}
}wa[N];
int cs[N],c[N];
ll ANS(ll x) {
return x < 2 ? 0: x * (x - 1) ;
}
void del(int pos) {
ll temp = --cs[c[pos]];
ans -= ANS(temp+1); ans += ANS(temp);
}
void add(int pos) {
ll temp = ++cs[c[pos]];
ans -= ANS(temp-1); ans += ANS(temp);
}
ll gcd(ll a,ll b) {
return b == 0 ? a : gcd(b, a%b);
}
bool cmp(node a,node b) {
if(a.l/sqrtn == b.l/sqrtn) return a.r < b.r;
return a.l < b.l;
}
int main(){
int n = read() ,m = read() ;
for(int i = 1 ; i <= n ; i++) c[i] = read();
for(int i = 1 ; i <= m ;i++) wa[i].l = read() , wa[i].r = read() , wa[i].id = i;
sqrtn = sqrt(0.5+n );
sort(wa+1,wa+1+m);
//sort(wa+1 , wa+1+m, cmp);
//orz;
for(int i = 1 ; i <= m ;i++) {
while (l < wa[i].l) del(l),l++;
while (l > wa[i].l) l--,add(l);
while (r < wa[i].r) r++,add(r);
while (r > wa[i].r) del(r),r--;
son[wa[i].id] = ans;
mo[wa[i].id] = ANS(r-l+1);
}
for(int i = 1; i <= m ;i++) {
if(son[i] == 0) {
cout<<"0/1\n";
continue;
}
ll temp = gcd(son[i],mo[i]);
printf("%lld/%lld\n",son[i]/temp,mo[i]/temp);
}
return 0;
}

莫队/se 优雅的暴力的更多相关文章

  1. 莫队 [洛谷2709] 小B的询问[洛谷1903]【模板】分块/带修改莫队(数颜色)

    莫队--------一个优雅的暴力 莫队是一个可以在O(n√n)内求出绝大部分无修改的离线的区间问题的答案(只要问题满足转移是O(1)的)即你已知区间[l,r]的解,能在O(1)的时间内求出[l-1, ...

  2. XOR and Favorite Number(莫队算法+分块)

    E. XOR and Favorite Number time limit per test 4 seconds memory limit per test 256 megabytes input s ...

  3. 【国家集训队2010】小Z的袜子(莫队)

    题面 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把 ...

  4. bzoj 3339 莫队

    题意: 求任意一个区间的SG函数. 想到线段树,但是线段树合并很麻烦. 线段树——分块. 分块的一个应用就是莫队算法. 怎么暴力递推呢? 从一个区间到另一个区间,Ans 取决于 Ans 和 加入和删除 ...

  5. 美团codem 数列互质 - 莫队

    题目描述 给出一个长度为 nnn 的数列 a1,a2,a3,...,an{ a_1 , a_2 , a_3 , ... , a_n }a​1​​,a​2​​,a​3​​,...,a​n​​,以及 mm ...

  6. BZOJ 3339 & 莫队+"所谓的暴力"

    题意: 给一段数字序列,求一段区间内未出现的最小自然数. SOL: 框架显然用莫队.因为它兹瓷离线. 然而在统计上我打了线段树...用&维护的结点...400w的线段树...然后二分查找... ...

  7. BZOJ 2038 小z的袜子 & 莫队算法(不就是个暴力么..)

    题意: 给一段序列,询问一个区间,求出区间中.....woc! 贴原题! 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过 ...

  8. D. Powerful array 莫队算法或者说块状数组 其实都是有点优化的暴力

    莫队算法就是优化的暴力算法.莫队算法是要把询问先按左端点属于的块排序,再按右端点排序.只是预先知道了所有的询问.可以合理的组织计算每个询问的顺序以此来降低复杂度. D. Powerful array ...

  9. Bzoj 2038: [2009国家集训队]小Z的袜子(hose) 莫队,分块,暴力

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 5763  Solved: 2660[Subm ...

随机推荐

  1. Redis集群搭建采坑总结

    背景 先澄清一下,整个过程问题都不是我解决的,我在里面就是起了个打酱油的角色.因为实际上我负责这个项目,整个过程也比较清楚.之前也跟具体负责的同事说过,等过段时间带他做做项目复盘.结果一直忙,之前做的 ...

  2. web前台界面的两种验证方式

    JSON的全称是"JavaScript Object Notation",意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式. 第一种: 用户体 ...

  3. java字符统计+字符串压缩

    要实习了.突然发现自己好像什么都不会,就去看看题吧.在网上看到一个字符串压缩的题.看了一眼,感觉用python很简单.一个for循环+字典就可以搞定. 但是呢,主要还是java.下面就用java来实现 ...

  4. BCC和libbpf的转换

    BCC和libbpf的转换 本文讲述如何将基于BCC的BPF应用转换为libbpf + BPF CO-RE.BPF CO-RE可以参见上一篇博文. 为什么是libbpf和BPF CO-RE? 历史上, ...

  5. Android-SDK接入-YSDK(应用宝1.7.0)

    SDK接入-YSDK(应用宝1.7.0)-2021-01-07 大家好,近期在多渠道打包平台,会定期遇到第三方SDK升级,所以很被动的是,我们也要跟随他们的步伐,及时升级.否则将面临第三方开发者站无法 ...

  6. CentOS 7 网卡注释

    TYPE=Ethernet # 网络类型为:EthernetPROXY_METHOD=none # 代理方式:关闭状态BROWSER_ONLY=no # 只是浏览器:否BOOTPROTO=static ...

  7. intel英特尔NUC主机bug大清除案例

    如果你的NUC进入HDMI无法在显示器显示,可以参考此文章的思路,尝试排除各种问题.接下来我讲述一下我的NUCbug清除历程. 我的NUC激动时刻 我的NUC是这个型号,直接上图了:英特尔(Intel ...

  8. VsCode/Pycharm配合python env 使用

    前言 用惯了vscode,这几天试了一下pycharm,还是回来了. pycharm一个好处就是python env 环境支持的比较好, vscode虽然也支持但是要改一些东西 env的使用查看我的上 ...

  9. vim 手动添加脚本头部信息

    vim /root/.vimrc 8,1 全部 set autoindent set tabstop=5 set shiftwidth=4 function AddTitle() call setli ...

  10. 【Oracle】instr()函数详解

    1)instr()函数的格式  (俗称:字符查找函数) 格式一:instr( string1, string2 )    /   instr(源字符串, 目标字符串) 格式二:instr( strin ...