莫队算法
题目:小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\n",q[i].A,q[i].B); 48 return 0; 49 }