首页 > 代码库 > bzoj2038 [2009国家集训队]小Z的袜子(hose)

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

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

【题解】

莫队出的裸莫队。

技术分享
# include <math.h>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 5e4 + 5;
const int mod = 1e9+7;

int n, m, bl[N], BLOCK;
int a[N];
ll ans[N], un[N];

struct quest {
    int l, r, id;
    quest() {}
    quest(int l, int r, int id) : l(l), r(r), id(id) {}
    inline friend bool operator < (quest a, quest b) {
        return bl[a.l] < bl[b.l] || (bl[a.l] == bl[b.l] && bl[a.r] < bl[b.r]);
    }
}q[N];

inline ll gcd(ll a, ll b) {
    return b ? gcd(b, a%b) : a;
}

int buc[N];
ll cnt = 0;
inline void add(int x) {
    cnt += buc[a[x]];
    ++buc[a[x]];
}

inline void del(int x) {
    --buc[a[x]];
    cnt -= buc[a[x]];
}
        

int main() {
    cin >> n >> m; BLOCK = sqrt(n);
    for (int i=1; i<=n; ++i) {
        scanf("%d", a+i);
        bl[i] = (i-1)/BLOCK+1;
    }
    for (int i=1, l, r; i<=m; ++i) {
        scanf("%d%d", &l, &r);
        q[i] = quest(l, r, i);
        un[i] = 1ll * (r-l+1) * (r-l) / 2;
    }
    sort(q+1, q+m+1);
    int L = 1, R = 0;
    for (int i=1; i<=m; ++i) {
        while(R < q[i].r) ++R, add(R);
        while(R > q[i].r) del(R), --R;
        while(L < q[i].l) del(L), ++L;
        while(L > q[i].l) --L, add(L);
        ans[q[i].id] = cnt;
    }
    for (int i=1; i<=m; ++i) {
        if(ans[i] == 0) puts("0/1");
        else {
            ll g = gcd(un[i], ans[i]);
            un[i] /= g, ans[i] /= g;
            printf("%lld/%lld\n", ans[i], un[i]);
        }
    }
    return 0;
}
View Code

 

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