Title: https://www.lydsy.com/JudgeOnline/problem.php?id=2038
is the MO team algorithm;
I wrote a chunk first, and the miserable WA:
#include <iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespaceStd;typedefLong Longll;int Constmaxn=50005;intn,m,k,c[maxn],rk[maxn],cnt[maxn],cnt2[maxn],ct=1, T,tmp[maxn];ll sum,s;structn{intl,r;ll Ans,ans2;} Q[MAXN];intRd () {intret=0;CharCh=GetChar (); while(ch<'0'|| Ch>'9') ch=GetChar (); while(ch>='0'&&ch<='9') ret=ret*Ten+ch-'0', ch=GetChar (); returnret;}BOOLcmpintXintY) {returnq[x].l<Q[Y].L;}BOOLCMP2 (intXintY) {returnq[x].r<Q[Y].R;}intCintx) {returnx* (x1)/2;} ll GCD (ll A,ll b) {returnB?GCD (b,a%b): A;}voidYF (N &x)//&{ll k=gcd (X.ans2,x.ans); X.ans/=k;x.ans2/=K;}voidSolveintk) {Sort (tmp+1, tmp+t+1, CMP2); Sum=0; memset (CNT,0,sizeofCNT); intl=k*k,r=l+1; for(intI=1; i<=t;i++) {memset (Cnt2,0,sizeofCnt2); while(r<=Q[TMP[I]].R) {Sum+=cnt[c[r]];cnt[c[r]]++; r++; } s=sum; for(intj=l;j>=q[tmp[i]].l;j--) {s+=cnt[c[j]]+cnt2[c[j]];cnt2[c[j]]++; } Q[tmp[i]].ans=s; Q[tmp[i]].ans2=c (q[tmp[i]].r-q[tmp[i]].l+1); YF (Q[tmp[i]); }}intMain () {n=rd (); M=rd (); k=sqrt (n); for(intI=1; i<=n;i++) c[i]=Rd (); for(intI=1; i<=m;i++) Q[i].l=rd (), Q[i].r=rd (), rk[i]=i; Sort (RK+1, rk+m+1, CMP); for(intI=1;(I-1) *k<n;i++) {T=0; while(q[rk[ct]].l<=i*k&&ct<=m) tmp[++t]=rk[ct],ct++; Solve (i); } for(intI=1; i<=m;i++) printf ("%lld/%lld\n", Q[I].ANS,Q[I].ANS2); return 0;}
embarrassing
Then looked at the solution, unexpectedly is another way, dealt with the formula: https://www.cnblogs.com/MashiroSky/p/5914637.html
So copy a bit:
#include <iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespaceStd;typedefLong Longll;int Constmaxn=50005;intn,m,k,c[maxn],cnt[maxn],blk[maxn];ll ans;structn{intL,r,bh;ll A, B;} Q[MAXN];intRd () {intret=0;CharCh=GetChar (); while(ch<'0'|| Ch>'9') ch=GetChar (); while(ch>='0'&&ch<='9') ret=ret*Ten+ch-'0', ch=GetChar (); returnret;}BOOLCMP (N x,n y) {returnblk[x.l]==blk[y.l]?x.r<y.r:blk[x.l]<BLK[Y.L];}BOOLCMP2 (N x,n y) {returnx.bh<y.bh;} ll GCD (ll A,ll b) {returna%b==0? B:GCD (b,a%b);}voidUpdateintXintval) {ans-=cnt[c[x]]*Cnt[c[x]]; CNT[C[X]]+=Val; Ans+=cnt[c[x]]*cnt[c[x]];}intMain () {n=rd (); M=rd (); k=sqrt (n); for(intI=1; i<=n;i++) C[i]=rd (), blk[i]= (i-1)/k+1;; for(intI=1; i<=m;i++) Q[i].l=rd (), Q[i].r=rd (), q[i].bh=i; Sort (q+1, q+m+1, CMP); for(intI=1, l=1, r=0; i<=m;i++) { while(L<Q[I].L) Update (l,-1), l++; while(L>Q[I].L) Update (L-1,1), l--; while(R<Q[I].R) Update (r+1,1), r++; while(R>Q[I].R) Update (r,-1), r--; if(q[i].l==Q[I].R) {Q[I].A=0; q[i].b=1;Continue; } q[i].a= (ll) ans-(r-l+1); Q[i].b= (LL) (r-l+1) * (R-L);//(LL)!!!ll K=GCD (Q[I].A,Q[I].B);//Put the molecule in front, in case the molecule is 0.Q[i].a/=k; Q[i].b/=K; } sort (Q+1, q+m+1, CMP2); for(intI=1; i<=m;i++) printf ("%lld/%lld\n", q[i].a,q[i].b); return 0;}
...
And then I saw a blog: https://www.cnblogs.com/xuwangzihao/p/5199174.html
My idea is still possible, add a point is to increase the number of points before the point of so many points, so the number of maintenance points can be;
The main problem is not strictly in accordance with the sub-block to do, just by the sub-block order can be guaranteed time complexity, so L and R Direct Global movement can be;
So the code suddenly became beautiful ... In the final analysis of their own such a chunk or write too ugly, can not guarantee the right ...
The code is as follows:
#include <iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespaceStd;typedefLong Longll;int Constmaxn=50005;intn,m,k,c[maxn],cnt[maxn],blk[maxn];ll ans;structn{intL,r,bh;ll A, B;} Q[MAXN];intRd () {intret=0;CharCh=GetChar (); while(ch<'0'|| Ch>'9') ch=GetChar (); while(ch>='0'&&ch<='9') ret=ret*Ten+ch-'0', ch=GetChar (); returnret;}BOOLCMP (N x,n y) {returnblk[x.l]==blk[y.l]?x.r<y.r:blk[x.l]<BLK[Y.L];}BOOLCMP2 (N x,n y) {returnx.bh<y.bh;} ll C (ll x) {returnx* (x1)/2;} ll GCD (ll A,ll b) {returna%b==0? B:GCD (b,a%b);}voidPopintx) {cnt[c[x]]--;ans-=cnt[c[x]];}//Note OrdervoidPushintx) {ans+=cnt[c[x]];cnt[c[x]]++;}intMain () {n=rd (); M=rd (); k=sqrt (n); for(intI=1; i<=n;i++) C[i]=rd (), blk[i]= (i-1)/k+1; for(intI=1; i<=m;i++) Q[i].l=rd (), Q[i].r=rd (), q[i].bh=i; Sort (q+1, q+m+1, CMP); for(intI=1, l=1, r=0; i<=m;i++) { while(L<Q[I].L) Pop (l), l++; while(L>Q[I].L) Push (L-1), l--; while(R<Q[I].R) Push (r+1), r++; while(R>Q[I].R) Pop (R), r--; Q[I].A=ans; Q[I].B=c (r-l+1); ll K=GCD (Q[I].A,Q[I].B);//Put the molecule in front, in case the molecule is 0.Q[i].a/=k; Q[i].b/=K; } sort (Q+1, q+m+1, CMP2); for(intI=1; i<=m;i++) printf ("%lld/%lld\n", q[i].a,q[i].b); return 0;}
bzoj2038 Small Z Socks (hose)--MO team algorithm