莫队也是暴力的一种,不过可以很有效的降低复杂度

如果我们已知[l, r]的答案,能在O(1)时间得到[l+1,r]的答案以及[l, r-1]的答案,即可使用莫队算法。

时间复杂度为O(n^1.5)。如果只能在logn的时间移动区间,则时间复杂度是O(n^1.5*logn)

也就是说如果已知[l, r]的答案,要求[l', r']的答案,我们可以通过|l – l'|+|r – r'|次转移内求得

一般来讲先分块,然后一块一块的求解(分块:http://blog.csdn.net/jaihk662/article/details/64508903)

求出每个询问的l落入第几块(pos[l]表示l在第pos[l]块),r不变

然后按pos[l]优先级排序,如果pos[l]相同,再按r排序

之后依次暴力就好了,也就是不停的进行|l – l'|+|r – r'|转移

复杂度O(n^1.5)

在同一个块里,总体的r最多移动n次,l最多移动sqrt(n)次,所以每一块的复杂度都是n+sqrt(n)==O(n)

然后总共有sqrt(n)块,所以总复杂度就是O(n^1.5)

2038: [2009国家集训队]小Z的袜子(hose)

Time Limit: 20 Sec  Memory Limit: 259 MB
Submit: 10845  Solved: 4890
[Submit][Status][Discuss]

Description

作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿。终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……
具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬。
你的任务便是告诉小Z,他有多大的概率抽到两只颜色相同的袜子。当然,小Z希望这个概率尽量高,所以他可能会询问多个(L,R)以方便自己选择。

Input

输入文件第一行包含两个正整数N和M。N为袜子的数量,M为小Z所提的询问的数量。接下来一行包含N个正整数Ci,其中Ci表示第i只袜子的颜色,相同的颜色用相同的数字表示。再接下来M行,每行两个正整数L,R表示一个询问。

Output

包含M行,对于每个询问在一行中输出分数A/B表示从该询问的区间[L,R]中随机抽出两只袜子颜色相同的概率。若该概率为0则输出0/1,否则输出的A/B必须为最简分数。(详见样例)

Sample Input

6 4
1 2 3 3 3 2
2 6
1 3
3 5
1 6

Sample Output

2/5
0/1
1/1
4/15

这题如何进行O(1)的转移呢?

令sum[i]表示区间内第i中颜色的袜子个数,那么有

所以你只需要O(1)修改sum[i]²就好了

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
typedef struct
{LL l, r, id;LL p, q;
}Res;
Res s[50005];
LL ans, c[50005], pos[50005], val[50005];
bool comp1(Res a, Res b)
{if(pos[a.l]==pos[b.l]){if(a.r<b.r)return 1;return 0;}if(a.l<b.l)return 1;return 0;
}
bool comp2(Res a, Res b)
{if(a.id<b.id)return 1;return 0;
}
LL Gcd(LL a, LL b)
{if(b==0)return a;return Gcd(b, a%b);
}
void Update(LL x, LL t)
{ans -= val[c[x]]*val[c[x]];val[c[x]] += t;ans += val[c[x]]*val[c[x]];
}
int main(void)
{LL i, l, r, n, m, block, k;while(scanf("%lld%lld", &n, &m)!=EOF){for(i=1;i<=n;i++)scanf("%lld", &c[i]);for(i=1;i<=m;i++){scanf("%lld%lld", &s[i].l, &s[i].r);s[i].id = i;}block = sqrt(n);for(i=1;i<=n;i++)pos[i] = (i-1)/block+1;sort(s+1, s+m+1, comp1);l = 1, r = 0;memset(val, 0, sizeof(val));ans = 0;for(i=1;i<=m;i++){while(r<s[i].r)r++, Update(r, 1);while(r>s[i].r)Update(r, -1), r--;while(l<s[i].l)Update(l, -1), l++;while(l>s[i].l)l--, Update(l, 1);if(s[i].l==s[i].r){s[i].p = 0;s[i].q = 1;continue;}s[i].p = ans-(s[i].r-s[i].l+1);s[i].q = (s[i].r-s[i].l+1)*(s[i].r-s[i].l);k = Gcd(s[i].p, s[i].q);s[i].p /= k;s[i].q /= k;}sort(s+1, s+m+1, comp2);for(i=1;i<=m;i++)printf("%lld/%lld\n", s[i].p, s[i].q);}return 0;
}

莫队(bzoj 2038: [2009国家集训队]小Z的袜子(hose))相关推荐

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

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

  2. BZOJ 2038: [2009国家集训队]小Z的袜子(hose) 分块

    分块大法好 2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MB Submit: 2938  Solved: 13 ...

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

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

  4. bzoj - 2038: [2009国家集训队]小Z的袜子(hose)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2038 莫队算法可以解决一类不修改.离线查询问题.而这题可以用莫队来做. *我是看这个论文学 ...

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

    题目描述 与 小B的询问 类似 对于一段区间[l,r],任选两个数构成排列的方案数A(r-l+1,2)=(r-l+1)*(r-l) 设num[i]为i在区间[l,r]内重复的次数,那么选出的两个数都是 ...

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

    题目传送门 1 /* 2 莫队算法:求出[l, r]上取出两只相同袜子的个数. 3 莫队算法是离线处理一类区间不修改查询类问题的算法.如果你知道了[L,R]的答案,可以在O(1)的时间下得到 4 [L ...

  7. 2038: [2009国家集训队]小Z的袜子(hose)+莫队入门

    题目链接:2038: [2009国家集训队]小Z的袜子(hose) 题目: Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再 ...

  8. 2038: [2009国家集训队]小Z的袜子(hose)

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

  9. BZOJ 2038: [2009国家集训队]小Z的袜子(莫队算法例题)

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

最新文章

  1. 线程安全(中)--彻底搞懂synchronized(从偏向锁到重量级锁)
  2. AS3与lua之间的交互
  3. openstack云主机无法绑定ip_智汇华云|OpenStack 虚拟机 GPU 性能优化
  4. 关于小程序·云开发峰会,你想get的干货全在这了!
  5. 关闭Mycelipse的拼写检查
  6. checkbox对齐排列
  7. 山寨威武 仿冒Xoom先于行货获得Android 4.0升级
  8. 让应用程序支持emoji字符 廖雪峰 / 编程 / 2017-4-20 22:01 / 阅读: 5051 什么是emoji?就是这些表情和符号:
  9. Sqoop是一款开源的工具,主要用于在HADOOP(Hive)与传统的数据库(mysql、oracle...)间进行数据的传递...
  10. php如何只删去汉字,php如何删除字符串中的中文
  11. 【html】非配对的标签
  12. Quartus与modelsim的初级使用教程
  13. 2021年“泰迪杯”数据分析技能赛A题
  14. Winrunner经验
  15. 部署企业级项目管理系统(蝉道)
  16. LeetCode 276:栅栏涂色
  17. 安装Kong和Konga
  18. ES面试问题和入门资料
  19. 乌尔维·阿西莫夫和 .art的不解情缘
  20. clip python_python中numpy模块下的np.clip()的用法

热门文章

  1. 用python画多来a梦-python 绘制哆啦A梦
  2. micropython入门指南-电子工业出版社-网上书店
  3. python编程100例-【python】编程语言入门经典100例--30
  4. python自学看什么书-自学Python一年,看了几十本书,我发现了这些捷径!
  5. Node介绍及环境配置~超级详细哦
  6. Vue实现按钮和文本框的切换
  7. echart保存图片的两种实现方式
  8. 【python 笔记】赋值语句和基本输入输出
  9. osg 镜面_浙江天梭手表镜面抛光
  10. 购物车ajax php json,Ajax+json实现购物车结算