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
| #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #define MAX_N 50000 using namespace std; typedef long long ll; int n, m; int col[MAX_N+5], f[MAX_N+5], pos[MAX_N+5]; ll gcd(ll a, ll b) {return (b == 0) ? a : gcd(b, a%b);} struct Query { int id, l, r; ll a, b; void reduction() {ll tmp = gcd(a, b); a /= tmp, b /= tmp;} } Q[MAX_N+5]; bool cmp_l(const Query &a, const Query &b) {return pos[a.l] < pos[b.l] || (pos[a.l] == pos[b.l] && a.r < b.r);} bool cmp_id(const Query &a, const Query &b) {return a.id < b.id;} void add(int c, ll &tmp, int x) {tmp += x*2*f[c]+1; f[c] += x;} int main() { scanf("%d%d", &n, &m); int magic = (int)sqrt((double)n+0.5); for (int i = 1; i <= n; i++) scanf("%d", &col[i]), pos[i] = (i-1)/magic+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+m+1, cmp_l); ll tmp = 0; int l = 1, r = 0; for (int i = 1; i <= m; i++) { if (l > Q[i].l) {for (int j = l-1; j >= Q[i].l; j--) add(col[j], tmp, 1); l = Q[i].l;} if (r < Q[i].r) {for (int j = r+1; j <= Q[i].r; j++) add(col[j], tmp, 1); r = Q[i].r;} if (l < Q[i].l) {for (int j = l; j < Q[i].l; j++) add(col[j], tmp, -1); l = Q[i].l;} if (r > Q[i].r) {for (int j = r; j > Q[i].r; j--) add(col[j], tmp, -1); r = Q[i].r;} if (Q[i].l == Q[i].r) {Q[i].a = 0, Q[i].b = 1; continue;} Q[i].a = tmp-(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].reduction(); } sort(Q+1, Q+m+1, cmp_id); for (int i = 1; i <= m; i++) printf("%lld/%lld\n", Q[i].a, Q[i].b); return 0; }
|