P1494 小Z的袜子 【普通莫队】

我的第二道莫队题,对莫队又有了自己的看法。

在第一题的基础上之上,觉得莫队有个很关键的地方在于 莫队所维护的值是什么,怎么推出维护的公式来。

这道题就是这样,一开始还没自己推出公式来,也有几个坑点。

题目链接:https://www.luogu.org/problemnew/show/P1494

题目大意:给出区间值,询问给定的【l, r】区间内抽到两只颜色一样的概率是多少。

思路:

1.首先很重要的推出公式来,设颜色相同的数量分别为a, b, c...那么对于给定的区间【l, r】,概率为 (a * (a  - 1) / 2+ b * (b - 1) / 2 + c * (c - 1) / 2 + ...) / ((r - l + 1) * (r - l) / 2),化简为 (a ^ 2 + b ^ 2 + c ^2 + ... - (r - l + 1)) / ((r - l + 1) * (r - l)),因此cnt维护区间内的值的数量,再推出如何维护平方和的值就行了。

2.计算的数据会爆int,需要用long long ,并且计算的式子要 * 1ll 来转化成long long型,才不会WA。

3.区间 l == r, 分子分母小于等于0时,直接记录 0 / 1

代码如下:

  1 #include<stdio.h>
  2 #include<math.h>
  3 #include<algorithm>
  4 using namespace std;
  5 const int MAXN = 50010;
  6
  7 int arr[MAXN];
  8 int cnt[MAXN]; //区间内出现次数
  9
 10 struct Qurey
 11 {
 12     int l, r, id;
 13     int pos; //所属的块
 14 }q[MAXN];
 15
 16 struct ANS
 17 {
 18     long long fz, fm;
 19 }ans[MAXN];
 20
 21 bool cmp(Qurey a, Qurey b)
 22 {
 23     if(a.pos == b.pos)
 24         return a.r < b.r;
 25     else
 26         return a.pos < b.pos;
 27 }
 28
 29 long long gcd(long long a, long long b)
 30 {
 31     long long c;
 32     while(b)
 33     {
 34         c = a % b;
 35         a = b;
 36         b = c;
 37     }
 38     return a;
 39 }
 40
 41 int main()
 42 {
 43     int n, m;
 44     scanf("%d%d", &n, &m);
 45     for(int i = 1; i <= n; i ++)
 46         scanf("%d", &arr[i]);
 47     int fk = sqrt(n);
 48     for(int i = 1; i <= m; i ++)
 49     {
 50         scanf("%d%d", &q[i].l, &q[i].r);
 51         q[i].id = i;
 52         q[i].pos = (q[i].l - 1) / fk + 1;
 53     }
 54     sort(q + 1, q + 1 + m, cmp);
 55     int left = 1, right = 0;
 56     long long sum = 0;
 57     for(int i = 1; i <= m; i ++)
 58     {
 59         if(q[i].l == q[i].r)
 60         {
 61             ans[q[i].id].fz = 0;
 62             ans[q[i].id].fm = 1;
 63             continue;
 64         }
 65         while(left > q[i].l)
 66         {
 67             left --;
 68             cnt[arr[left]] ++;
 69             sum += 2 *1ll* cnt[arr[left]] - 1;
 70         }
 71         while(right < q[i].r)
 72         {
 73             right ++;
 74             cnt[arr[right]] ++;
 75             sum += 2 *1ll* cnt[arr[right]] - 1;
 76         }
 77         while(left < q[i].l)
 78         {
 79             cnt[arr[left]] --;
 80             sum -= 2 *1ll* cnt[arr[left]] + 1;
 81             left ++;
 82         }
 83         while(right > q[i].r)
 84         {
 85             cnt[arr[right]] --;
 86             sum -= 2 *1ll* cnt[arr[right]] + 1;
 87             right --;
 88         }
 89         long long fz = sum - (right - left + 1);
 90         long long fm = 1ll*(right - left + 1) * (right - left);
 91         if(fz <= 0 || fm <= 0)
 92         {
 93             ans[q[i].id].fz = 0;
 94             ans[q[i].id].fm = 1;
 95             continue;
 96         }
 97         long long temp = gcd(fz, fm);
 98         fz /= temp, fm /= temp;
 99         ans[q[i].id].fz = fz, ans[q[i].id].fm = fm;
100     }
101     for(int i = 1; i <= m; i ++)
102     {
103         printf("%lld/%lld\n", ans[i].fz, ans[i].fm);
104     }
105     return 0;
106 }

原文地址:https://www.cnblogs.com/yuanweidao/p/10988957.html

时间: 2024-08-30 18:02:04

P1494 小Z的袜子 【普通莫队】的相关文章

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

莫队..先按sqrt(n)分块, 然后按块的顺序对询问排序, 同块就按右端点排序. 然后就按排序后的顺序暴力求解即可. 时间复杂度O(n1.5) ------------------------------------------------------------------------------ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 50009; int N,

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

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 10239  Solved: 4659[Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命--具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两

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

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7687  Solved: 3516[Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只

kyeremal-bzoj2038-[2009国家集训队]-小z的袜子(hose)-莫队算法

bzoj2038-[2009国家集训队]-小z的袜子(hose) F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  Manacher Logout 捐赠本站 Notice:省选季快乐&另求历年World Final数据,谢谢&OJ试题突破3000大关! 2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MB Submit: 

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

题目链接:2038: [2009国家集训队]小Z的袜子(hose) 题目: Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬.你的任务便是告诉小Z,他有多大的概率抽到两只颜色相同的袜子

P1494 [国家集训队]小Z的袜子(莫队)

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

P1494 [国家集训队]小Z的袜子(莫队算法)

莫队板子 代码 #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #define int long long using namespace std; struct Query{ int l,r,aid; }query[55000]; int ansa[55000],ansb[55000],c[55000],blocknum,midans,sz,belong[

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

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

[国家集训队]小Z的袜子(莫队,概率)

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

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

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