码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj-2038 小Z的袜子 hose

时间:2015-08-05 10:39:23      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:bzoj   莫队算法   

题意:

给出一个长度为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; 
}





bzoj-2038 小Z的袜子 hose

标签:bzoj   莫队算法   

原文地址:http://blog.csdn.net/ww140142/article/details/47282245

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!