【BZOJ2038】小Z的袜子(hose)(莫队算法 + 分块)

来源:互联网 发布:开淘宝店怎么进货 编辑:程序博客网 时间:2024/06/11 09:55

记录一个菜逼的成长。。

转自参考博客
莫队算法可用于解决一类可离线且在得到区间[l,r]的答案后,能在O(1)O(logn2)得到区间[l,r+1][l1,r]的答案的问题

问题:
给出n个数字,m次询问,每次询问在区间[li,ri]
之间任选两个数字相等的概率是多少。(n,q<=50000)
在区间[l,r]中,这个概率是:

vi=1C(2,f(i))C(2,rl+1)=vi=1f(i)2vi=1f(i)(rl+1)(rl)

(v表示数字值,f(i)表示数字i在区间内出现的次数)

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 50000 + 10;int pos[maxn],f[maxn];struct Node{    int l,r,id;    LL a,b;    bool operator < (const Node &a) const{        if(pos[l] != pos[a.l])return pos[l] < pos[a.l];        return r < a.r;    }    void update()    {        LL gcd = __gcd(a,b);        a /= gcd;b /= gcd;    }}Q[maxn];int a[maxn];bool cmp(Node a,Node b){    return a.id < b.id;}void update(LL &ans,int ind,int v){    ans = ans + 2 * v * f[a[ind]] + 1;    f[a[ind]] += v;}void solve(int n,int m){    int l = 1,r = 0;    LL ans = 0;    for( int i = 1; i <= m; i++ ){        if(r < Q[i].r){            for( r = r + 1; r < Q[i].r; r++ )                update(ans,r,1);            update(ans,r,1);        }        if(l > Q[i].l){            for( l = l - 1; l > Q[i].l; l-- ){                update(ans,l,1);            }            update(ans,l,1);        }        if(r > Q[i].r){            for( ; r > Q[i].r; r-- )                update(ans,r,-1);        }        if(l < Q[i].l){            for( ; l < Q[i].l; l++ )                update(ans,l,-1);        }        if(Q[i].l == Q[i].r){            Q[i].a = 0;            Q[i].b = 1;            continue;        }        Q[i].a = ans - (Q[i].r - Q[i].l + 1),Q[i].b = (LL)(Q[i].r - Q[i].l + 1) * (Q[i].r - Q[i].l);        Q[i].update();    }    sort(Q+1,Q+1+m,cmp);    for( int i = 1; i <= m; i++ ){        printf("%lld/%lld\n",Q[i].a,Q[i].b);    }}int main(){    int n,m;    scanf("%d%d",&n,&m);    for( int i = 1; i <= n; i++ )        scanf("%d",a+i);    int k = (int)(sqrt(n));    for( int i = 1; i <= n; i++ ){        pos[i] = (i - 1) / k + 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);    solve(n,m);    return 0;}
0 0
原创粉丝点击