【莫队算法】【国家集训队2010】小Z的袜子

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

Hint

样例说明: 
询问1:共C(5,2)=10种可能,其中抽出两个2有1种可能,抽出两个3有3种可能,概率为(1+3)/10=4/10=2/5。 
询问2:共C(3,2)=3种可能,无法抽到颜色相同的袜子,概率为0/3=0/1。 
询问3:共C(3,2)=3种可能,均为抽出两个3,概率为3/3=1/1。 
注:上述C(a, b)表示组合数,组合数C(a, b)等价于在a个不同的物品中选取b个的选取方案数。 
数据范围: 
30%的数据中 N,M ≤ 5000; 
60%的数据中 N,M ≤ 25000; 
100%的数据中 N,M ≤ 50000,1 ≤ L < R ≤ N,Ci ≤ N。

题解

  第一次看到这题,第一想法是用线段树或者树状数组维护一下,但仔细一想,似乎不行,因为本题的区间不满足加和性质。于是就需要用到莫队算法。

  莫队算法可以解决已经知道区间[l,r]的答案,然后可以在O(1)(或者O(log N))的时间内求出[l,r+1],[l,r-1],[l-1,r],[l+1,r]的答案的问题。  

  现在知道,在区间[l,r]中,答案是 (X2+Y2+Z2.......−(r−l+1))/((r−l+1)(r−l))(X,Y,Z分别代表区间中不同颜色袜子的个数)。

  显然,这是满足上面的性质的。假如我们按照读入顺序依次求解的话,复杂度为O(n2),不是特别满意。

  这时我们就需要用到莫队算法,莫队算法的核心就是改变求解询问的顺序,从而减少运算的次数。那么,怎么样改变顺序来使速度最快呢?可以把每个区间都看做2维平面上的点,这些点的距离为横,纵坐标之差,然后我们可以O(N logN)求出这些平面点的曼哈顿最小生成树,但这样太复杂(而且我也不会)。

  所以我们可以用分块来处理,将N 分成N½块,然后我们维护一下左端点所在块的编号。以左端点的编号为第一关键字,右端点的编号为第二关键字排序;然后以排序后的顺序依次求解(所以是离线的),在求解的过程中维护答案的值。这样做的复杂度为 O(N∗N½)。以下是证明过程:

  • 时间复杂度就是左右端点移动的次数。
  • 对于右端点的移动:因为一共只有N½个块,每个块中右端点最多移动n次,所以复杂度为O(N×N½)。
  • 对于左端点的移动:如果在同一块中移动,那么是O(N½)的,如果跨越了块,那么最多跨越O(N),那么复杂度为O(N×N½+N)
  • 综上,时间复杂度为O(N×N½)。

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
#define REP(i,a,b) for(register int i=(a),_end_=(b);i<=_end_;i++)
#define DREP(i,a,b) for(register int i=(a),_end_=(b);i>=_end_;i--)
#define EREP(i,a) for(register int i=start[(a)];i;i=e[i].next)
inline int read()
{
int sum=,p=;char ch=getchar();
while(!((''<=ch && ch<='') || ch=='-'))ch=getchar();
if(ch=='-')p=-,ch=getchar();
while(''<=ch && ch<='')sum=sum*+ch-,ch=getchar();
return sum*p;
} const int maxn=5e4+; int n,m;
int w[maxn]; void init()
{
n=read();m=read();
REP(i,,n)w[i]=read();
} struct query {
int l,r,t,sx;
}; struct ans {
ll a,b;
}; query qu[maxn];
ans Ans[maxn];
int k; bool cmp(const query a,const query b)
{
if(a.t==b.t)return a.r<b.r;
return a.t<b.t;
} ll co[maxn]={};
ll A; void work(int x,int add)
{
A-=co[w[x]]*co[w[x]];
co[w[x]]+=add;
A+=co[w[x]]*co[w[x]]; } void doing()
{
k=(int)sqrt(n);
REP(i,,m)
{
qu[i].l=read();qu[i].r=read();
qu[i].t=(qu[i].l-)/k+;
qu[i].sx=i;
}
sort(qu+,qu+m+,cmp);
int l=,r=;
REP(i,,m)
{
while(l>qu[i].l)work(l-,),l--;
while(l<qu[i].l)work(l,-),l++;
while(r>qu[i].r)work(r,-),r--;
while(r<qu[i].r)work(r+,),r++;
if(qu[i].l==qu[i].r)
{
Ans[qu[i].sx]={,};continue;
}
Ans[qu[i].sx]={A-(r-l+),(ll)(r-l+)*(r-l)};
}
REP(i,,m)
{
ll d=__gcd(Ans[i].a,Ans[i].b);
if(d>)cout<<Ans[i].a/d<<"/"<<Ans[i].b/d<<endl;
else cout<<Ans[i].a<<"/"<<Ans[i].b<<endl;
}
} int main()
{
init();
doing();
return ;
}

【国家集训队2010】小Z的袜子[莫队算法]的更多相关文章

  1. 【bzoj2038】[国家集训队2010]小Z的袜子 莫队

    莫队:就是一坨软软的有弹性的东西Duang~Duang~Duang~ 为了防止以左端点为第一关键字以右端点为第二关键字使右端点弹来弹去,所以让左端点所在块为关键字得到O(n1.5)的时间效率,至于分块 ...

  2. [国家集训队][bzoj2038] 小Z的袜子 [莫队]

    题面: 传送门 思路: 又是一道标准的莫队处理题目,但是这道题需要一点小改动:求个数变成了求概率 我们思考:每次某种颜色从i个增加到i+1个,符合要求的情况多了多少? 原来的总情况数是i*(i-1)/ ...

  3. AC日记——[国家集训队2010]小Z的袜子 cogs 1775

    [国家集训队2010]小Z的袜子 思路: 传说中的莫队算法(优雅的暴力): 莫队算法是一个离线的区间询问算法: 如果我们知道[l,r], 那么,我们就能O(1)的时间求出(l-1,r),(l+1,r) ...

  4. 洛谷 1775. [国家集训队2010]小Z的袜子

    1775. [国家集训队2010]小Z的袜子 ★★★   输入文件:hose.in   输出文件:hose.out   简单对比时间限制:1 s   内存限制:512 MB [题目描述] 作为一个生活 ...

  5. 数据结构(莫队算法):国家集训队2010 小Z的袜子

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

  6. [国家集训队2010]小Z的袜子

    ★★★   输入文件:hose.in   输出文件:hose.out   简单对比 时间限制:1 s   内存限制:512 MB [题目描述] 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜 ...

  7. 1775. [国家集训队2010]小Z的袜子

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

  8. [日常摸鱼]bzoj2038[2009国家集训队]小Z的袜子-莫队算法

    今天来学了下莫队-这题应该就是这个算法的出处了 一篇别人的blog:https://www.cnblogs.com/Paul-Guderian/p/6933799.html 题意:一个序列,$m$次询 ...

  9. cogs1772 [国家集训队2010]小Z的袜子

    沉迷于文化的我N年没更blog了...(\(N \in (0,1)\)) 然后回到机房就沉迷于 \(generals.io\) 无法自拔...QAQ 然后想打一遍splay(然后是LCT),然后放弃了 ...

随机推荐

  1. 【问题解决】java中为什么不建议使用DataInputStream 的readLine()方法

    常用方法 int read(byte[] b) 从包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组 b 中. int read(byte[] b, int off, int len) 从包含 ...

  2. MapReduce 原理与 Python 实践

    MapReduce 原理与 Python 实践 1. MapReduce 原理 以下是个人在MongoDB和Redis实际应用中总结的Map-Reduce的理解 Hadoop 的 MapReduce ...

  3. Jquery实现两级联动

    最后结果如下: 关键代码如下: <select name="customerCondition['credibilityBegin']" id="credibili ...

  4. node.js核心模块

    全局对象 global 是全局变量的宿主 全局变量 在最外层定义的 全局对象的属性 隐士定义的变量(未定义直接赋值的变量) 当定义一个全局变量时 这个变量同时也会成为全局对象的属性 反之亦然 注意: ...

  5. Django_项目初始化

    如何初始Django运行环境? 1. 安装python 2. 创建Django项目专用的虚拟环境 http://www.cnblogs.com/2bjiujiu/p/7365876.html 3.进入 ...

  6. 苹果系统css样式变化

    原因:苹果自带样式覆盖了 参考文章比较详细,就不自己写了,copy了一份~~~ @参考文章 只要在样式里面加一句去掉css去掉iPhone.iPad的默认按钮样式就可以了!~ input[type=& ...

  7. MySQL模糊查询中通配符的转义

    sql中经常用like进行模糊查询,而模糊查询就要用到百分号“%”,下划线“_”这些通配符,其中“%”匹配任意多个字符,“_”匹配单个字符.如果我们想要模糊查询带有通配符的字符串,如“60%”,“us ...

  8. jQuery的Nicescroll滚动条插件使用方法

    Nicescroll滚动条插件是一个非常强大的基于jQuery的滚动条插件,不需要增加额外的css,几乎全浏览器兼容.ie6+,实现只需要一段代码,侵入性非常小,样式可完全自定义,支持触摸事件,可在触 ...

  9. Unity 使用Plugins接入安卓SDK 基础篇

    一.须知 本帖适合对安卓一点基础都没有,有一定Unity基础.刚刚接完一个某文档很简单的渠道SDk,也当是自己总结一下. 二.Unity中的目录创建与理解. Plugins:插件目录,该目录再编译项目 ...

  10. rsync命令解释

    -v, --verbose 详细模式输出-q, --quiet 精简输出模式-c, --checksum 打开校验开关,强制对文件传输进行校验-a, --archive 归档模式,表示以递归方式传输文 ...