"BZOJ3781" Little B's inquiry

**Test Instructions** : There is a sequence that contains an integer between N 1~k. He had a total of M inquiries, each asking for a given interval [L. R], the value of Sigma (C (i) ^2), where I is the value from 1 to K, where C (i) represents the number I in [L. The number of repetitions in R]

The puzzle : Beginner mo Team Algorithm, almost understand the situation with Mo team, for this offline, the interval length of +1 can be O (1) To modify the answer to the question, the use of the MO team algorithm is the most water

Dividing n into sqrt (n) blocks will ask for the first keyword in the block where the left endpoint is located, the exact position of the right end point is the second keyword, and then use the pointer l,r to move continuously violently to the left and next end of the query and continuously O (1) To update the answer so that the left endpoint moves up to sqrt (n) *m+ SQRT (n) *sqrt (n), the right endpoint moves a distance of up to sqrt (n) *n times, so the total complexity is O (n*sqrt (n))

For the subject, set the original interval for [l,r], we translate from [l,r] to [l,r+1] example, because only the r+1 this number, we set r+1 this number in [L,r] in the occurrence of C (i), then the original number of contributions to the answer is C (i) *c (i), plus r+ 1 after the contribution has become (c (i) +1) * (c (i) +1), then the contribution of r+1 this number is 2*c (i) +1, and then use it to update the answer, and finally C (i) + + is good

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include < cmath>using namespace Std;const int maxn=50010;typedef long long ll;struct node{int qa,qb,ans,org;} Q[maxn];int n,m,siz;ll sum;int c[maxn];ll s[maxn];int gcd (int a,int b) {return (b==0)? A:GCD (b,a%b);} BOOL CMP (node A,node b) {if ((a.qa-1)/siz== (b.qa-1)/siz) return A.qb<b.qb;return (a.qa-1)/siz< (B.qa-1)/siz;} BOOL CMP2 (node A,node b) {return a.org<b.org;} void Add (int x) {sum+=s[c[x]],s[c[x]]++;} void rem (int x) {s[c[x]]--, sum-=s[c[x]];} int main () {scanf ("%d%d", &n,&m), siz= (int) sqrt ((double) n), int i;ll a,b,g;for (i=1;i<=n;i++) scanf ("%d", &c[i]); for (i=1;i<=m;i++) scanf ("%d%d", &Q[I].QA,&Q[I].QB), Q[i].org=i;sort (q+1,q+m+1,cmp); int L=1,r =0;for (i=1;i<=m;i++) {while (R<Q[I].QB) Add (++r), while (R>Q[I].QB) REM (r--), while (L<Q[I].QA) REM (l++); while (L>Q[I].QA) add (--l); q[i].ans=sum;} Sort (Q+1,Q+M+1,CMP2); for (i=1;i<=m;i++) {a=q[i].ans,b= (LL) (Q[I].QB-Q[I].QA) * (q[i].qb-q[i].qa+1)/2,G=GCD (A, B), if (a==0) printf ("0/1\n"); elseprintf ("%lld/%lld\n", a/g,b/g);} return 0;}

"BZOJ2038" [2009 countries Training team] small Z socks (hose)

**Test Instructions** : There are n number, m query, each query to find the interval [l,r] in any of the two numbers so that the probability of the same two numbers

Solution: The other is the same as above, but the answer becomes: (s (i) indicates the number of occurrences of i)

Ignoring the denominator, for the newly added r+1, the obvious contribution is S (i), then S (i) + +

The question I long long open seems not quite right ~

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include < cmath>using namespace Std;const int maxn=50010;typedef long long ll;struct node{int qa,qb,ans,org;} Q[maxn];int n,m,siz;ll sum;int c[maxn];ll s[maxn];int gcd (int a,int b) {return (b==0)? A:GCD (b,a%b);} BOOL CMP (node A,node b) {if ((a.qa-1)/siz== (b.qa-1)/siz) return A.qb<b.qb;return (a.qa-1)/siz< (B.qa-1)/siz;} BOOL CMP2 (node A,node b) {return a.org<b.org;} void Add (int x) {sum+=s[c[x]],s[c[x]]++;} void rem (int x) {s[c[x]]--, sum-=s[c[x]];} int main () {scanf ("%d%d", &n,&m), siz= (int) sqrt ((double) n), int i;ll a,b,g;for (i=1;i<=n;i++) scanf ("%d", &c[i]); for (i=1;i<=m;i++) scanf ("%d%d", &Q[I].QA,&Q[I].QB), Q[i].org=i;sort (q+1,q+m+1,cmp); int L=1,r =0;for (i=1;i<=m;i++) {while (R<Q[I].QB) Add (++r), while (R>Q[I].QB) REM (r--), while (L<Q[I].QA) REM (l++); while (L>Q[I].QA) add (--l); q[i].ans=sum;} Sort (Q+1,Q+M+1,CMP2); for (i=1;i<=m;i++) {a=q[i].ans,b= (LL) (Q[I].QB-Q[I].QA) * (q[i].qb-q[i].qa+1)/2,G=GCD (A, B), if (a==0) printf ("0/1\n"); elseprintf ("%lld/%lld\n", a/g,b/g);} return 0;}

"BZOJ3781, 2038" Mo Team algorithm 2 water problem