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

来源:互联网 发布:知乎lolfaker 编辑:程序博客网 时间:2024/06/10 20:10

传送门 :http://www.lydsy.com/JudgeOnline/problem.php?id=2038

题意:略

思路:这类没有修改的区间乱搞问题 很容易想到莫队 注意:map进行计数会T

ACcode:

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 50010;int a[maxn], n, m;const int SZ = 230;LL ans1[maxn], ans2[maxn];struct node{    LL l, r, id;} q[maxn];bool cmp(node a, node b){    if(a.l / SZ == b.l / SZ) return a.r < b.r;    return a.l / SZ < b.l / SZ;}LL C(LL x, LL y){    if(y > x) return 0;    return x * (x - 1ll) / 2ll;}LL num[maxn];int main(){    scanf("%d%d", &n, &m);    for(int i = 1; i <= n; i++)    scanf("%d", &a[i]);    for(int i = 1; i <= m; i++)    {        int l = i, r = i, id = i;        scanf("%d%d", &l, &r);        q[i] = {l, r, id};    }    sort(q + 1, q + 1 + m, cmp);    LL l = q[1].l, r = q[1].l - 1;    LL tmp = 0;    for(int i = 1; i <= m; i++)    {        while(l < q[i].l )        tmp-=num[a[l]]*(num[a[l]]-1ll)/2,num[a[l]]--,tmp+=num[a[l]]*(num[a[l]]-1ll)/2 ,l++;        while(r < q[i].r )        r++,tmp-=num[a[r]]*(num[a[r]]-1ll)/2,num[a[r]]++,tmp+=num[a[r]]*(num[a[r]]-1ll)/2;        while(l > q[i].l )        l--,tmp-=num[a[l]]*(num[a[l]]-1ll)/2,num[a[l]]++,tmp+=num[a[l]]*(num[a[l]]-1ll)/2;        while(r > q[i].r )        tmp-=num[a[r]]*(num[a[r]]-1ll)/2,num[a[r]]--,tmp+=num[a[r]]*(num[a[r]]-1ll)/2, r--;        ans1[q[i].id] = tmp;        ans2[q[i].id] = C(r - l + 1ll, 2ll);    }    for(int i = 1; i <= m; i++)    {        if(ans1[i] == 0)            printf("0/1\n");        else        {            int k = __gcd(ans1[i], ans2[i]);            printf("%lld/%lld\n", ans1[i] / k, ans2[i] / k);        }    }    return 0;}


阅读全文
0 0