1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| #include <iostream> #include <algorithm> #include <cstdio> #include <cmath>
using namespace std;
typedef long long ll;
const int N = 50010;
struct node { int l, r, id; };
int n, m, a[N]; int block, belong[N], tot, l[N], r[N]; ll num[N], res, mol[N], den[N]; node q[N];
void build() { block = sqrt(n); tot = n / block; if (n % block) tot++; for (int i = 1; i <= tot; i++) { l[i] = (i - 1) * block + 1; r[i] = i * block; } r[tot] = n; for (int i = 1; i <= n; i++) belong[i] = (i - 1) / block + 1; }
bool cmp(node a, node b) { if (belong[a.l] != belong[b.l]) return belong[a.l] < belong[b.l]; return a.r < b.r; }
void add(int x) { res = res - num[a[x]] * (num[a[x]] - 1) / 2; num[a[x]]++; res = res + num[a[x]] * (num[a[x]] - 1) / 2; }
void sub(int x) { res = res - num[a[x]] * (num[a[x]] - 1) / 2; num[a[x]]--; res = res + num[a[x]] * (num[a[x]] - 1) / 2; }
ll c(int n) { return (ll)n * (n - 1) / 2; }
ll gcd(ll a, ll b) { return 0 == b ? a : gcd(b, a % b); }
int main() { scanf("%d%d", &n, &m); build(); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= m; i++) { scanf("%d%d", &q[i].l, &q[i].r); den[i] = c(q[i].r - q[i].l + 1); q[i].id = i; } sort(q + 1, q + m + 1, cmp); int L = 1, R = 0; for (int i = 1; i <= m; i++) { while (q[i].l < L) add(--L); while (q[i].r > R) add(++R); while (q[i].l > L) sub(L++); while (q[i].r < R) sub(R--); mol[q[i].id] = res; } for (int i = 1; i <= m; i++) { ll d = gcd(mol[i], den[i]); if (0 == mol[i]) printf("0/1\n"); else printf("%lld/%lld\n", mol[i] / d, den[i] / d); } return 0; }
|