bzoj-2038 小Z的袜子 hose

题意:

给出一个长度为n的序列,每次询问一个区间[l,r];

查询在这个区间中取出两个数恰好相等的概率;

每个数大小在[0,n]内,概率用既约分数表示;

题解:

考虑一个区间的答案,显然是合法方案数/取数的所有可能;

也就是 ∑C[同种数字个数][2]/C[r-l+1][2];

但是这个东西对一次询问的处理复杂度是O(r-l+1)的;

那么考虑上莫队算法,处理这样的区间问题;

很容易发现每次修改边界可以做到O(1)完成;

void update(int x,int op)
{
    now-=C[s[a[x]]][2];
    s[a[x]]+=op;
    now+=C[s[a[x]]][2];
}

C[i][j]是组合数,s[x]是当前区间x的数量,now是当前答案;

然后将询问排序处理,第一关键字左端点所在块,第二关键字右端点

当块的大小为√n时,可以证明复杂度不会超过O(n√n);

然后每个区间转移到下一个区间就是有复杂度保证的暴力咯;

码量似乎不算太巨大,思想也比较简单,很神的暴力算法;

代码:

#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 51000
using namespace std;
struct query
{
    int pos,l,r,no;
}Q[N];
int a[N],s[N],ans_up[N],ans_do[N],C[N][3],now;
bool cmp(query a,query b)
{
    if(a.pos==b.pos)
    return a.r<b.r;
    return a.pos<b.pos;
}
int gcd(int a,int b)
{
    if(!a||!b)  return a?a:b;
    int t=a%b;
    while(t)
    {
        a=b,b=t;
        t=a%b;
    }
    return b;
}
void update(int x,int op)
{
    now-=C[s[a[x]]][2];
    s[a[x]]+=op;
    now+=C[s[a[x]]][2];
}
int main()
{
    int n,m,k,i,j,l,r;
    scanf("%d%d",&n,&m);
    int bk=sqrt(n);
    for(i=1;i<=n;i++)
        scanf("%d",a+i);
    for(i=0;i<=n;i++)
    {
        C[i][0]=1;
        for(j=1;j<=2;j++)
            C[i][j]=C[i-1][j]+C[i-1][j-1];
    }
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&Q[i].l,&Q[i].r);
        Q[i].no=i,Q[i].pos=Q[i].l/bk;
    }
    sort(Q+1,Q+m+1,cmp);
    l=0,r=0,now=0,s[50001]=1,a[0]=50001;
    for(i=1;i<=m;i++)
    {
        while(l<Q[i].l)  update(l++,-1);
        while(l>Q[i].l)  update(--l, 1);
        while(r<Q[i].r)  update(++r, 1);
        while(r>Q[i].r)  update(r--,-1);
        ans_up[Q[i].no]=now;
        ans_do[Q[i].no]=C[r-l+1][2];
    }
    for(i=1;i<=m;i++)
    {
        k=gcd(ans_up[i],ans_do[i]);
        printf("%d/%d\n",ans_up[i]/k,ans_do[i]/k);
    }
    return 0;
}
时间: 2024-10-05 02:02:07

bzoj-2038 小Z的袜子 hose的相关文章

bzoj 2038 小Z的袜子(hose)(莫队算法)

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

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> #includ

BZOJ 2038 小z的袜子 &amp; 莫队算法(不就是个暴力么..)

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

bzoj 2038 小z的袜子 莫队例题

莫队,利用可以快速地通过一个问题的答案得到另一问题的答案这一特性,合理地组织问题的求解顺序,将已解决的问题帮助解决当前问题,来优化时间复杂度. 典型用法:处理静态(无修改)离线区间查询问题. 线段树也是处理区间问题的一个有力工具,它和莫队算法各有特点: 线段树可以支持修改,并且单次操作时间复杂度一般为O(log),支持在线,但是要求可以进行快速的区间合并操作,两个区间如不能快速合并(f(n)*O(log)>O(n)),则用线段树就没有什么实际价值了(暴力都比它块) 莫队算法可以解决某些线段树不能

HYSBZ 2038 小Z的袜子(hose) (莫队算法入门)

题意:取一段区间,求区间中任取两个数相同的概率: 思路:所求概率P=(A*(A-1)/2+B*(B-1)/2+......)/(R-L+1)*(R-L)/2化简得P=(A*A+B*B+......+Z*Z-(R-L+1))/(R-L+1)*(R-L); 将询问区间左端点放在同一分块中处理,每次处理一个块中的所有询问,对于同一块,询问右端点按严格递增处理,左端点不断移动: #include<cstdio> #include<cstring> #include<cmath>

bzoj 2038 小Z的袜子

好久没写题解了=_= ,整个暑假就没写过,还是决定写写吧,所以挑了这道大水题. 这是标准的莫队算法的问题,但由于可能数据水还是别的什么原因,不用曼哈顿最小生成树也可以过.具体就是按询问区间的左端点分块, 块内按右端点排序,然后暴力…… 真的是暴力,太暴力了,直到AC以后我才相信这么暴力真的可以在O(N^1.5)的时间复杂度内过掉. 块内具体就是右端点递增,左端点由于在块内并不是有序的,所以左端点就会晃来晃去,真是太暴力了…… 上代码: #include <cstdio> #include &l

HYSBZ 2038 小Z的袜子(hose) (莫队算法)

题意:中文题. 析:很著名的莫队算法,先把这个求概率的式子表达出来,应该是分子:C(x1, 2) + C(x2, 2) + C(x3, 2) + ... + C(xn, 2)  分母:C(n, 2),然后化成分数的表达形式,[x1(x1-1)+x2(x2-1)+...+xn(xn-1)] / (n*(n-1))  然后再化简得到 (sigma(xi*xi)  - n) / (n*(n-1)) ,然后就是对每个区间进行运算,离线,把所以的序列分成sqrt(n)块,然后用两个指针,进行对数据的计算.

BZOJ 2038 小Z的袜子(莫队算法)

莫队算法如果我们已知[l,r]的答案,能在O(1)时间得到[l+1,r]的答案以及[l,r-1]的答案,即可使用莫队算法.时间复杂度为O(n^1.5).如果只能在logn的时间移动区间,则时间复杂度是O(n^1.5*log n).其实就是找一个数据结构支持插入.删除时维护当前答案. 这道题的话我们很容易用数组来实现,做到O(1)的从[l,r]转移到[l,r+1]与[l+1,r]. 那么莫队算法怎么做呢?以下都是在转移为O(1)的基础下讨论的时间复杂度.另外由于n与m同阶,就统一写n.如果已知[l

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

[算法]莫队 [题解] BZOJ 2038 2009国家集训队 小Z的袜子(hose) 莫队算法 莫队--讲稿? 施工中--

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

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