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

来源:互联网 发布:p2p理财系统源码 编辑:程序博客网 时间:2024/06/10 19:12

裸的莫队?
概率:合法事件个数/总事件个数

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int MAXN = 51000;struct Query{    int l,r,id;} Q[MAXN];int n,m;int col[MAXN],Belong[MAXN],cnt[MAXN];int block,sizm;struct Ans{    LL up,down;    void reduce()    {        LL gcd = __gcd(up,down);        up /= gcd;        down /= gcd;    }} res[MAXN];bool cmp(const Query& a, const Query& b){    if(Belong[a.l] == Belong[b.l])        return a.r < b.r;    return Belong[a.l] < Belong[b.l];}int main(){    while(scanf("%d %d",&n,&m) != EOF)    {        block = sqrt(n);        for(int i = 1; i <= n; ++i)        {            scanf("%d",&col[i]);            Belong[i] = (i-1)/block+1;        }        for(int i = 1; i <= m; ++i)        {            scanf("%d %d",&Q[i].l,&Q[i].r);            Q[i].id = i;        }        sort(Q+1,Q+1+m,cmp);        memset(cnt,0,sizeof(cnt));        int L = 1, R = 0;        LL temp = 0;        for(int i = 1; i <= m; ++i)        {            while(L < Q[i].l)            {                if(cnt[col[L]] > 1) temp -= (LL)(cnt[col[L]]-1)*cnt[col[L]]/2;                --cnt[col[L]];                if(cnt[col[L]] > 1) temp += (LL)(cnt[col[L]]-1)*cnt[col[L]]/2;                ++L;            }            while(L > Q[i].l)            {                --L;                if(cnt[col[L]] > 1) temp -= (LL)(cnt[col[L]]-1)*cnt[col[L]]/2;                ++cnt[col[L]];                if(cnt[col[L]] > 1) temp += (LL)(cnt[col[L]]-1)*cnt[col[L]]/2;            }            while(R < Q[i].r)            {                ++R;                if(cnt[col[R]] > 1) temp -= (LL)(cnt[col[R]]-1)*cnt[col[R]]/2;                ++cnt[col[R]];                if(cnt[col[R]] > 1) temp += (LL)(cnt[col[R]]-1)*cnt[col[R]]/2;            }            while(R > Q[i].r)            {                if(cnt[col[R]] > 1) temp -= (LL)(cnt[col[R]]-1)*cnt[col[R]]/2;                --cnt[col[R]];                if(cnt[col[R]] > 1) temp += (LL)(cnt[col[R]]-1)*cnt[col[R]]/2;                --R;            }            res[Q[i].id].up = temp;            res[Q[i].id].down = (LL)(R-L+1)*(R-L)/2;            res[Q[i].id].reduce();        }        for(int i = 1; i <= m; ++i)            printf("%lld/%lld\n",res[i].up,res[i].down);    }    return 0;}
阅读全文
0 0