BZOJ:2038: [2009国家集训队]小Z的袜子(hose)(莫队算法模板)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2038
解题心得:
- 第一次接触莫队算法,很神奇,很巧妙。莫队算法主要就是用来解决多次询问时维护区间内的信息。维护区间信息第一个想法肯定是线段树,但是线段树维护的区间信息量很少(如最大值,最小值,SUM,GCD等),接触过尺取法的人都知道有时候在处理区间询问的时候可以先将区间排序然后再尺取。莫队算法也用了类似的思维,先对询问区间进行排序,这里排序就用了分块的思想,并不是严格的按照左端点,或者右端点排序,更多的是按照分的块进行排序,这样就减少了维护区间的大幅度乱跳动。
- 莫队的复杂度分析,每个块长度unit为sqrt(n),如果l端点不在同一个块内需要移动到另一个块内,移动次数最多为2*unit,l在一个块内,r所在位置无法确定,但是排序后可以保证是单调递增的,所以最多移动n次,总共有n/unit个块,最坏要移动n/unit个块,所以总的最坏的复杂度是O(n * sqrt(n) + n * n /sqrt(n) )
- 这个题来说算概率还是简单的 (Sum(每种袜子个数 2 ) - (r - l + 1)) / ((r - l + 1) * (r - l)),分母可以O(1)内得到,分子可以使用莫队维护
/**************************************************************
Problem: 2038
User: swust5120164059
Language: C++
Result: Accepted
Time:3404 ms
Memory:7560 kb
****************************************************************/ //
// ┏┛ ┻━━━━━┛ ┻┓
// ┃ ┃
// ┃ ━ ┃
// ┃ ┳┛ ┗┳ ┃
// ┃ ┃
// ┃ ┻ ┃
// ┃ ┃
// ┗━┓ ┏━━━┛
// ┃ ┃ 神兽保佑
// ┃ ┃ 代码无BUG!
// ┃ ┗━━━━━━━━━┓
// ┃ ┣┓
// ┃ ┏┛
// ┗━┓ ┓ ┏━━━┳ ┓ ┏━┛
// ┃ ┫ ┫ ┃ ┫ ┫
// ┗━┻━┛ ┗━┻━┛
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <math.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+; struct NODE {
ll l, r, A, B, pos;
}q[maxn]; ll n, m, color[maxn], B[maxn], cnt_color[maxn]; void init() {
scanf("%lld%lld",&n,&m);
ll div = (ll) sqrt(n);
for(int i=;i<=n;i++) {
scanf("%lld", &color[i]);
B[i] = i/div + ;
}
for(int i=;i<m;i++) {
scanf("%lld%lld",&q[i].l, &q[i].r);
q[i].pos = i;
}
} bool cmp1(NODE a, NODE b) {
if(B[a.l] == B[b.l])
return a.r < b.r;
return a.l < b.l;
} bool cmp2(NODE a, NODE b) {
return a.pos < b.pos;
} ll ans = ;
void add(ll pos, ll va) {
ans -= pow(cnt_color[color[pos]], );
cnt_color[color[pos]] += va;
ans += pow(cnt_color[color[pos]], );
} int main() {
init();
sort(q, q+m, cmp1);
int l = , r = ;
for(int i=;i<m;i++) {
//左右端点跳转
while(l < q[i].l)
add(l++, -);
while(l > q[i].l)
add(--l, );
while(r < q[i].r)
add(++r, );
while(r > q[i].r)
add(r--, -); //只有一个袜子概率为0
if(q[i].l == q[i].r) {
q[i].A = ;
q[i].B = ;
continue;
}
q[i].A = ans - (q[i].r - q[i].l + );
q[i].B = (q[i].r - q[i].l + ) * (q[i].r - q[i].l);
}
sort(q, q+m, cmp2);
for(int i=;i<m;i++) {
ll GCD = __gcd(q[i].A, q[i].B);
printf("%lld/%lld\n", q[i].A/GCD, q[i].B/GCD);
}
return ;
}
BZOJ:2038: [2009国家集训队]小Z的袜子(hose)(莫队算法模板)的更多相关文章
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 7687 Solved: 3516[Subm ...
- Bzoj 2038: [2009国家集训队]小Z的袜子(hose) 莫队,分块,暴力
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 5763 Solved: 2660[Subm ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) ( 莫队 )
莫队..先按sqrt(n)分块, 然后按块的顺序对询问排序, 同块就按右端点排序. 然后就按排序后的顺序暴力求解即可. 时间复杂度O(n1.5) --------------------------- ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)&&莫对算法
这里跟曼哈顿最小生成树没有太大的关系. 时间复杂度证明: [BZOJ2038 小Z的袜子 AC代码] 排序方式: 第一关键字:l所在的块: 第二关键字:r从小到大. #include<cstdi ...
- bzoj 2038: [2009国家集训队]小Z的袜子(hose) (莫队)
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜 ...
- BZOJ2038: [2009国家集训队]小Z的袜子(hose) -- 莫队算法 ,,分块
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 3577 Solved: 1652[Subm ...
- [BZOJ2038] [2009国家集训队]小Z的袜子(hose) 莫队算法练习
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 10299 Solved: 4685[Sub ...
- BZOJ 2038: [2009国家集训队]小Z的袜子 (莫队)
题目传送门:小Z的袜子 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… ...
- 【bzoj2038】[2009国家集训队]小Z的袜子(hose) 莫队算法
原文地址:http://www.cnblogs.com/GXZlegend/p/6803860.html 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终 ...
- BZOJ2038: [2009国家集训队]小Z的袜子(hose) 莫队算法
要使用莫队算法前提 ,已知[l,r]的答案,要能在logn或者O(1)的时间得到[l+1,r],[l-1,r],[l,r-1],[l,r+1],适用于一类不修改的查询 优美的替代品——分块将n个数分成 ...
随机推荐
- 怎样在linux下编写C程序并编译执行
一.Hello, world! 在linux下输入:(以hello.c为例)首先选中文件要保存的路径(如:cd work)vi hello.c(要编辑的文件名) 输入程序:# include<s ...
- QT隐含共享类 QSharedData QSharedDataPointer
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/davidsu33/article/details/28857391 QT中非常多类都实现了隐含共享比 ...
- 【洛谷5280】[ZJOI2019] 线段树(线段树大力分类讨论)
点此看题面 大致题意: 给你一棵线段树,两种操作.一种操作将每棵线段树复制成两个,然后在这两个线段树中的一个上面进行\(Modify(l,r)\).另一种操作询问所有线段树的\(tag\)总和. 大力 ...
- BZOJ4538:[HNOI2016]网络(树链剖分,堆)
Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做 一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有 ...
- POJ 1416 Shredding Company【dfs入门】
题目传送门:http://poj.org/problem?id=1416 Shredding Company Time Limit: 1000MS Memory Limit: 10000K Tot ...
- 【转】不错的linux下通用的java程序启动脚本
虽然写起动shell的频率非常不高...但是每次要写都要对付一大堆的jar文件路径,新加jar包也必须要修改起动shell. 在网上找到一个挺好的通用shell脚本. 只需要修改一些配置变量,就可以用 ...
- CF821E 【Okabe and El Psy Kongroo】
首先我们从最简单的dp开始 \(dp[i][j]=dp[i-1][j]+dp[i-1][j+1]+dp[i-1][j-1]\) 然后这是一个O(NM)的做法,肯定行不通,然后我们考虑使用矩阵加速 \( ...
- 【洛谷P1083】[NOIP2012]借教室
借教室 [题目描述] 在n天中每天有一个可以借出的教室数,有m个订单,每个订单从第l天到第r天要借用x个教室.问能否满足所有的订单,若不能,输出第一个不能满足的订单编号. 思路: 1.1 ≤ n,m ...
- Android学习笔记_71_Android 多个项目之间如何引用 项目怎样打jar包
一.将整个项目作为资源文件 1.需要将被应用的项目设置为库项目. 2.将该项目的配置文件中的四大组件清空,例如下面代码: <?xml version="1.0" encodi ...
- Android学习笔记_38_图片的拖动、缩放功能和多点触摸
一.基础知识: 引用 理论上 Android可以处理 多达256 个手指的触摸,大概只有章鱼哥能享受这种技术带来的便利.就编程人员来说,编写多点触摸和单点触摸的方式几乎一模一样.其奥秘在于Motion ...