BZOJ2038小Z的袜子——莫队

2024-02-04 12:08
文章标签 莫队 袜子 bzoj2038

本文主要是介绍BZOJ2038小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

【样例解释】

询问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。


这道题显然要维护区间的信息。我们先考虑暴力算法。如果我们要将区间li,ri变为lj,rj,则我们要从li到lj的区间里修改颜色的累加值,比如若li< lj,则从i到j的颜色c[i]的总记sum[c[i]]-1。通过这样不停的维护,就可以求出正解。
但问题是如果数据十分卡,得在不同的区间里跳来跳去,则时间复杂度会很慢。而莫队算法将读入的询问按一定的顺序sort一遍,然后再从li跳到lj,ri跳到rj即可。经过sort,就不会有乱跳的现象,能极大节省时间。
那么应该按照什么样的顺序sort?这里可以用分块思想,另bl[i]表示i所在的分块,如果bl[li]!=bl[lj],则按l大小排序,如果bl[li]=bl[lj],则按r排序,这样排序可以保证在同一分块里r单调递增,而分块的顺序也递增,即可极大减低复杂度。
本题只要用组合数学推论,结合莫队算法即可解题。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll read(){char c;ll x;while(c=getchar(),c<'0'||c>'9');x=c-'0';while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
ll n,m,c[50005],sum[50005],cnt,bl[50005],block,l,r;
struct node{ll mother,son,l,r,pl;
}q[50005];
ll cmp(node a,node b){return bl[a.l]==bl[b.l]?a.r<b.r:a.l<b.l;
}
ll comp(node a,node b){return a.pl<b.pl;}
ll sq(ll x){return x*x;}
void change(ll p,ll num){cnt-=sq(sum[c[p]]);sum[c[p]]+=num;cnt+=sq(sum[c[p]]);
}
ll gcd(ll x,ll y){return x%y==0?y:gcd(y,x%y);}
int main()
{n=read();m=read();block=sqrt(n);for(ll i=1;i<=n;i++) bl[i]=i/block+1;for(ll i=1;i<=n;i++) c[i]=read();for(ll i=1;i<=m;i++){q[i].l=read(),q[i].r=read(),q[i].pl=i;}sort(q+1,q+1+m,cmp);l=1,r=0;for(ll i=1;i<=m;i++){for(ll j=l;j<q[i].l;j++) change(j,-1),l++;for(ll j=l;j>q[i].l;j--) change(j-1,1),l--;for(ll j=r;j<q[i].r;j++) change(j+1,1),r++;for(ll j=r;j>q[i].r;j--) change(j,-1),r--; if(q[i].l==q[i].r){q[i].son=0;q[i].mother=1;continue;}q[i].son=cnt-(q[i].r-q[i].l+1);q[i].mother=1ll*(q[i].r-q[i].l+1)*(q[i].r-q[i].l);if(q[i].son==0){q[i].mother=1;continue;}ll g=gcd(q[i].mother,q[i].son);q[i].son/=g;q[i].mother/=g;}sort(q+1,q+1+m,comp);for(ll i=1;i<=m;i++) printf("%lld/%lld\n",q[i].son,q[i].mother);return 0;
}

这篇关于BZOJ2038小Z的袜子——莫队的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/677433

相关文章

BZOJ 2038 小Z的袜子(hose) (莫队离线)

题目地址:BZOJ 2038 裸的莫队算法。 代码如下: #include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>#in

曼哈顿距离最小生成树与莫队算法

一、曼哈顿距离最小生成树 曼哈顿距离最小生成树问题可以简述如下: 给定二维平面上的N个点,在两点之间连边的代价为其曼哈顿距离,求使所有点连通的最小代价。 朴素的算法可以用O(N2)的Prim,或者处理出所有边做Kruskal,但在这里总边数有O(N2)条,所以Kruskal的复杂度变成了O(N2logN)。 但是事实上,真正有用的边远没有O(N2)条。我们考虑每个点会和其他一些什

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

作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿。 终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命。 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R的袜子中随机选出两只来穿。 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬。 你的任务便是告诉小Z,他

SP3267 DQUERY - D-query(莫队算法,区间不同数)

题意: 询问区间有多少个不同的数。 思路: 莫队裸题。 十分神奇的算法,我觉得关键就是离线排序,但是左端点的判据是第几块(分块),右端点的判据是大小。就这么一点点小改动,大大减小了复杂度ORZ。 #pragma GCC optimize(2)#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>us

2019CCPC湘潭邀请赛 Chika and Friendly Pairs(莫队+树状数组)

Problem Description Chika gives you an integer sequence a1,a2,…,an and m tasks. For each task, you need to answer the number of “friendly pairs” in a given interval. friendly pair: for two integers a

CodeForces 220B : Little Elephant and Array 莫队

传送门 题意 小象喜欢和数组玩。现在有一个数组 a a a,含有 n n n个正整数,记第 i i i个数为 a i a_i ai​ 现在有 m m m个询问,每个询问包含两个正整数 l j l_j lj​和 r j ( 1 < = l j < = r j < = n ) r_j(1<=l_j<=r_j<=n) rj​(1<=lj​<=rj​<=n),小象想知道在 l l l到 r r r之

bzoj 2038: [2009国家集训队]小Z的袜子(莫队算法)

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MB Submit: 15386  Solved: 6996 [Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿。终于有一天,小Z再也无法忍受这恼人的找袜

CodeForces - 940F Machine Learning —— 带修改莫队

You come home and fell some unpleasant smell. Where is it coming from? You are given an array a. You have to answer the following queries: You are given two integers l and r. Let ci be the number of

CodeForces 617E XOR and Favorite Number(莫队)

题目链接:点击打开链接 题意:给n个数和一个k,有很多次查询,每次查询有l,r,求[l,r]有多少个子区间的xor之和等于k 思路:首先,亦或运算存在一个性质,即a^a=0,a^0=a,那么a^b=c,则a^b^b=a=b^c(两边同时亦或b),区间[l,r]的区间亦或和为a[l]^a[l+1]^...^a[r]=a[1]^...^a[l-1]^a[1]^...^a[r]=sum[r]^sum

洛谷P5072 [YNOI2015]盼君勿忘 莫队+unordered_set+毒瘤卡常

在太阳西斜的这个世界里,置身天上之森。等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去、逐渐消逝的未来。我回来了,纵使日薄西山,即便看不到未来,此时此刻的光辉,盼君勿忘。————世界上最幸福的女孩 珂朵莉最可爱了,珂朵莉的题最毒瘤了qwq 题目链接:传送门 这是一个自带大常数选手被毒瘤 l x l lxl lxl卡常数,从开 O 2 O2 O2才 82