莫队算法

题目:小Z的袜子

这题是一道标准的莫队模板。

具体推导看这里

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 5e4+10;
 5 struct mo{
 6     int l, r, id;
 7     ll A, B;
 8 }q[N];
 9 int col[N], Be[N], unit;
10 ll sum[N], ans;
11 int n, m;
12 ll S(ll x){return x*x;}
13 ll GCD(ll x, ll y) {
14     return y?GCD(y,x%y):x;
15 }
16 bool cmp(mo a, mo b) {
17     return Be[a.l] == Be[b.l] ? a.r < b.r: a.l < b.l;
18 }
19 bool CMP(mo a, mo b) {
20     return a.id < b.id;
21 }
22 void revise(int x, int add) {
23     ans -= S(sum[col[x]]);
24     sum[col[x]] += add, ans += S(sum[col[x]]);
25 }
26 int main() {
27     scanf("%d%d", &n, &m);unit = sqrt(n);
28     for(int i = 1; i <= n; i ++) scanf("%d", &col[i]), Be[i] = i/unit + 1;
29     for(int i = 1; i <= m; i ++) scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i;
30     sort(q+1,q+1+m, cmp);
31     int l = 1, r = 0;
32     for(int i = 1; i <= m; i ++) {
33         while(l < q[i].l) revise(l, -1), l++;
34         while(l > q[i].l) revise(l-1, 1), l--;
35         while(r < q[i].r) revise(r+1, 1), r++;
36         while(r > q[i].r) revise(r, -1), r--;
37         if(q[i].l == q[i].r) {
38             q[i].A = 0, q[i].B = 1;
39             continue;
40         }
41         q[i].A = ans - (q[i].r-q[i].l+1);
42         q[i].B = 1LL*(q[i].r-q[i].l+1)*(q[i].r-q[i].l);
43         ll gcd = GCD(q[i].A,q[i].B);
44         q[i].A /= gcd, q[i].B /= gcd;
45     }
46     sort(q+1,q+1+m,CMP);
47     for(int i = 1; i <= m; i ++) printf("%lld/%lld
",q[i].A,q[i].B);
48     return 0;
49 }
原文地址:https://www.cnblogs.com/xingkongyihao/p/9407022.html