传送门
写在前面:莫队竟如此暴力……
思路:当初我对这个题的第一感觉——这个区间问题可以用线段树或者树状数组?答案当然是不能,于是我就去简单学了下莫队算法。在我看来,莫队(分块版,不是二维曼哈顿距离什么什么最小生成树)就是分块排序优化暴力查找,减少查找区间之间的覆盖长度,从而优化时间复杂度,有一种说法很精彩

如果我们已知[l,r]的答案,能在O(1)时间得到[l+1,r]的答案以及[l,r-1]的答案,即可使用莫队算法。时间复杂度为O(n^1.5)。如果只能在logn的时间移动区间,则时间复杂度是O(n^1.5*log
n)。 其实就是找一个数据结构支持插入、删除时维护当前答案。

这道题的话我们很容易用数组来实现,做到O(1)的从[l,r]转移到[l,r+1]与[l+1,r]。

那么莫队算法怎么做呢?以下都是在转移为O(1)的基础下讨论的时间复杂度。另外由于n与m同阶,就统一写n。
如果已知[l,r]的答案,要求[l’,r’]的答案,我们很容易通过|l – l’|+|r – r’|次转移内求得。

对于它的时间复杂度分析

将n个数分成sqrt(n)块。 按区间排序,以左端点所在块内为第一关键字,右端点为第二关键字,进行排序,也就是以(pos [l],r)排序
然后按这个排序直接暴力,复杂度分析是这样的:
1、i与i+1在同一块内,r单调递增,所以r是O(n)的。由于有n^0.5块,所以这一部分时间复杂度是n^1.5。
2、i与i+1跨越一块,r最多变化n,由于有n^0.5块,所以这一部分时间复杂度是n^1.5
3、i与i+1在同一块内时变化不超过n^0.5,跨越一块也不会超过n^0.5,忽略*2。由于有n个数,所以时间复杂度是n^1.5
于是就是O(n^1.5)了

这道题是比较模板的莫队分块了,对于一个区间询问[L,R],我们要求的ans是
ans=(Σsum(color[i])−1)∗sum(color[i])/2)/((R−L+1)∗(R−L))ans=(Σsum(color[i])-1)*sum(color[i])/2)/((R-L+1)*(R-L))
简化可得
ans=(Σ(sum(color[i])2)−(R−L+1))/((R−L+1)∗(R−L))ans=(Σ(sum(color[i])^2)-(R-L+1))/((R-L+1)*(R-L))
其中sum(color[i])sum(color[i])指第i种颜色在[L,R]中出现的次数
那么我们现在求出各个询问区间中sum(color[i])2sum(color[i])^2就行了,具体实现方法参照代码
注意:
1.当一种颜色数量ci增加1时,我们可以看出ans=ans−ci2+(ci+1)2ans=ans-ci^2+(ci+1)^2,简化可得ans=ans+(ci∗2+1)ans=ans+(ci*2+1),同样减少1时,ans=ans−ci2+(ci−1)2ans=ans-ci^2+(ci-1)^2,简化得ans=ans+(ci∗2−1)ans=ans+(ci*2-1),这样做的好处是减少乘法且可用位运算,优化常数(然而并没有什么卵用)
2.极限数据50000*50000如果不用longlong会教你做人←_←
代码:

#include"bits/stdc++.h"
#define LL long long
using namespace std;
int n,m,last_l=1,last_r;
LL ans,p;
int color[50010],block[50010];
LL sum[50010];
struct os
{LL part,l,r,nume,deno;//nume指分子,deno指分母
}q[50010];
int cmp1(os xx,os yy)
{if (block[xx.l]<block[yy.l]) return 1;if (block[xx.l]>block[yy.l]) return 0;return xx.r<yy.r;
}
int cmp2(os xx,os yy){return xx.part<yy.part;}
inline LL gcd(LL x,LL y)
{if (!y) return x;return gcd(y,x%y);
}
main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++) scanf("%d",&color[i]);block[0]=sqrt(n);for (int i=1;i<=n;i++)block[i]=(i-1)/block[0]+1;for (int i=1;i<=m;i++)scanf("%d%d",&q[i].l,&q[i].r),q[i].part=i;sort(q+1,q+m+1,cmp1);   for (int i=1;i<=m;i++){q[i].deno=(q[i].r-q[i].l+1)*(q[i].r-q[i].l);if (last_r<q[i].r){for (int j=last_r+1;j<=q[i].r;j++)ans+=((sum[color[j]]<<1)+1),sum[color[j]]++;}if (last_r>q[i].r){for (int j=last_r;j>q[i].r;j--)ans-=((sum[color[j]]<<1)-1),sum[color[j]]--;}if (last_l>q[i].l){for (int j=last_l-1;j>=q[i].l;j--)ans+=((sum[color[j]]<<1)+1),sum[color[j]]++;}if (last_l<q[i].l){for (int j=last_l;j<q[i].l;j++)ans-=((sum[color[j]]<<1)-1),sum[color[j]]--;}q[i].nume=ans-(q[i].r-q[i].l+1);last_l=q[i].l;last_r=q[i].r;}sort(q+1,q+m+1,cmp2);for (int i=1;i<=m;i++){if (!q[i].nume){printf("0/1\n");continue;}p=gcd(q[i].nume,q[i].deno);printf("%lld/%lld\n",q[i].nume/p,q[i].deno/p);}
}

【BZOJ2038】小Z的袜子,第一次的莫队算法相关推荐

  1. BZOJ2038 : [2009国家集训队]小Z的袜子(hose)(莫队算法)

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MB Submit: 19269 Solved: 8851 [Sub ...

  2. 小Z的袜子(hose) (莫队算法入门)

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

  3. BZOJ 2038: [2009国家集训队]小Z的袜子(hose)【莫队算法裸题学习笔记】

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MB Submit: 9894  Solved: 4561 [Su ...

  4. (HYSBZ - 2038)小Z的袜子(hose)(莫队)

    题目链接:P1494 [国家集训队]小Z的袜子 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目是中文的,我在这就不解释题意了. 这道题目考察的是莫队算法,还是老样子,模板不再多 ...

  5. bzoj2038: [2009国家集训队]小Z的袜子(hose)(莫队)

    题目传送门 强啊学了一发莫队. 解法: 刚看到这题没啥思路就只有一个n方的垃圾.. %题解说是莫队,学了一发. 莫队大概就是用来优化暴力的一个东西. 这道题的数学解法相必大家都会.. 在n个袜子里面选 ...

  6. [BZOJ 2038][2009国家集训队]小Z的袜子(hose)(莫队)

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

  7. BZOJ2038 小Z的袜子 (莫队算法)

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=2038 专题练习: http://acm.hust.edu.cn/vjudge/conte ...

  8. BZOJ2038 小Z的袜子(hose)

    题目链接 莫队求区间[L,R]中数字相同的pair数,然后求GCD即可. #include<stdio.h> #include<string.h> #include<io ...

  9. [BZOJ2038] [2009国家集训队] 小Z的袜子(hose) (莫队)

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

最新文章

  1. 工作的未来:敏捷人士瑞典大会上午议程回顾
  2. NYOJ541 最强DE 战斗力(第五届省赛试题)
  3. RuntimeError: CUDA out of memory. Tried to allocate 132.00 MiB (GPU 2; 3.95 GiB total capacity; 3.41
  4. Coherence Step by Step 第三篇 缓存(一) 介绍(翻译)
  5. linux下kafka安装与配置
  6. StreamSets sdc rpc 测试
  7. 2022年R2移动式压力容器充装操作证考试题库及答案
  8. 电脑知识 - bin文件夹是什么
  9. CVR预估论文阅读笔记:一次性解决三大难题
  10. 区块链隐私保护(一): 交易层的隐私保护机制
  11. Android EditText 获得焦点不显示光标
  12. Python3.7 安装Airflow 报错tenacity.async import AsyncRetrying
  13. 盛迈坤电商:店铺自然流量怎么提升
  14. php如何读取doc文档,php创建读取 word.doc文档
  15. 5月已更新PS2021m1直装版!Photoshop2021 Mac真正完美适配M1芯片!完美解决2019黑屏闪退卡启动界面等所有问题!
  16. 园林系统优秀党员推荐材料_事迹材料-园林绿化公司党员先进个人事迹材料
  17. python英译汉库模块_Python 进阶之路-翻译模块
  18. 1024——依然是写给你
  19. 案例学习|Python实现某医院药品销售分析
  20. Vue3.0报错:The component has been registered but not used vue/no-unused-components,关闭eslint

热门文章

  1. 一条数据的HBase之旅,简明HBase入门教程4:集群角色
  2. 《一张图看懂华为云BigData Pro鲲鹏大数据解决方案》
  3. Memcached与Redis有什么区别
  4. Android 布局 优先显示右侧的控件
  5. html两行文字右侧对齐,HTML在同一行左右对齐文本
  6. python tkinter的基础用法
  7. tinypng 批量处理插件_分享六款逆天的Excel插件,高效处理数据必备!低调使用...
  8. 求最小公倍数与最大公约数(C语言)
  9. 微服务主见传递ID还是json_后台管理系统之微服务搭建
  10. php jwt怎么保存再客户端,php – 如何将JWT添加到授权标头?