The main topic: given n points, each point has a color, m inquiry, each asked a range randomly selected two points the same probability of the same number
Otz-mo Team algorithm ...
The specifics of this, whether it's a block or a Manhattan minimum spanning tree, I'm not going to talk about it.
The practice of this problem is to record a CNT array representing how many of each color in the current interval
Add a point with a color of x on ans+=cnt[x] and cnt[x]++
Reduce the point of a color x to cnt[x]--then ans-=cnt[x]
Then add or remove a point O (1) out of the solution here, explain it, because the expression in my code is too brutal.
I've written all two versions of it ... And that's the result.
It's Manhattan's smallest spanning tree, and here's the chunking.
So the block either time or code complexity on the end of the explosion mmst ... A decisive chunk of Dafa. 0.0
But MmSt wrote that really big on the 0.0 give people a kind of "Wow plug I even this high-end algorithm have done あたいは most powerful ne!" "The Illusion of Qaq
In a word, two versions are all pasted up.
Sub-block:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include < Algorithm> #define M 50500using namespace std;struct query{int L,r,pos;bool operator < (const query &x) const;} Q[m];int n,m,block;int a[m],belong[m],cnt[m];p air<unsigned int,unsigned int> ans[M];unsigned int now;bool query: : operator < (const query &x) const{if (BELONG[L]==BELONG[X.L]) return R<x.r;return BELONG[L]<BELONG[X.L];} int main () {#ifdef popoqqqfreopen ("2038.in", "R", stdin) freopen ("2038.out", "w", stdout); #endifint i;cin>>n> >m;for (i=1;i<=n;i++) scanf ("%d", &a[i]); for (i=1;i<=m;i++) scanf ("%d%d", &Q[I].L,&Q[I].R), Q[i] .pos=i;block=static_cast<int> (Ceil (sqrt (n))); for (i=1;i<=n;i++) belong[i]= (i-1)/block+1;sort (q+1,q+m+1) ; int L=1,r=0;for (i=1;i<=m;i++) {while (R<Q[I].R) now+=cnt[a[++r]]++;while (R>Q[I].R) now-=--cnt[a[r--]]; while (L<Q[I].L) now-=--cnt[a[l++]];while (L>Q[I].L) now+=cnt[a[--l]]++;unsigned int temp= (Unsigned) (r-l+1) * (r-l) >>1;unsigned int gcd=__gcd (now,temp); Ans[q[i].pos]=make_pair (NOW/GCD,TEMP/GCD);} for (i=1;i<=m;i++) printf ("%u/%u\n", Ans[i].first,ans[i].second);}
Manhattan minimum Spanning Tree
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 50500using namespace Std;struct edge{int X,y,f;bool operator < (const edge &z) Const{return F < z.f;}} E[m<<2];struct point{int X,y,pos,key;bool operator < (const point &p) const{if (x==p.x) return y>p.y; return x>p.x;}} Points[m];struct query{int L,r;} Q[m];struct abcd{int To,next;} Table[m<<1];int head[m],tot;int n,m,k,a[m],c[m];int fa[m];int l=1,r=0,cnt[m];unsigned int now;pair<unsigned int,unsigned int>ans[m];int Find (int x) {if (!fa[x]| | FA[X]==X) return Fa[x]=x;return fa[x]=find (fa[x]);} void Add (int x,int y) {table[++tot].to=y;table[tot].next=head[x];head[x]=tot;} void Update (int x,int y) {for (; x;x-=x&-x) if (POINTS[Y].X+POINTS[Y].Y<POINTS[C[X]].X+POINTS[C[X]].Y) c[x]=y;} int Get_ans (int x) {int re=0;for (; x<=m;x+=x&-x) if (Points[c[x]].x+points[c[x]].y<points[re].x+points[re]. y) Re=c[x];return re;} void Calculate () {int i,temp=0;static pair<Int,int>b[m];for (i=1;i<=m;i++) B[i]=make_pair (points[i].y-points[i].x,i); sort (b+1,b+m+1); for (i=1;i<=m; i++) {if (i==1| | B[i].first!=b[i-1].first) ++temp;points[b[i].second].key=temp;} Sort (points+1,points+m+1); memset (c,0,sizeof c); for (i=1;i<=m;i++) {Temp=get_ans (Points[i].key); if (temp) {e[++k] . F=points[temp].x+points[temp].y-points[i].x-points[i].y;e[k].x=points[i].pos;e[k].y=points[temp].pos;} Update (Points[i].key,i);}} void Kruskal () {int i;sort (e+1,e+k+1), for (i=1;i<=k;i++) {int x=e[i].x,y=e[i].y;if (Find (x)!=find (y)) {fa[find (x)]= Find (y); Add (x, y), add (y,x);}}} void DFS (int x,int from) {int i;while (R<Q[X].R) now+=cnt[a[++r]]++;while (L>Q[X].L) Now+=cnt[a[--l]]++;while (r >Q[X].R) Now-=--cnt[a[r--]];while (L<Q[X].L) now-=--cnt[a[l++]];unsigned int temp= (unsigned) (r-l+1) * (r-l) > >1;unsigned int GCD=__GCD (now,temp); Ans[x]=make_pair (NOW/GCD,TEMP/GCD); for (I=head[x];i;i=table[i].next) {if ( Table[i].to==from) Continue;dfs (table[i].to,x), while (R<Q[X].R) Now+=cnt[a[++r]]++;while (L>q[x]. L) Now+=cnt[a[--l]]++;while (R>Q[X].R) now-=--cnt[a[r--]];while (L<Q[X].L) now-=--cnt[a[l++];}} int main () {#ifdef popoqqqfreopen ("2038.in", "R", stdin) freopen ("2038.out", "w", stdout); #endifint i;cin>>n> >m;for (i=1;i<=n;i++) scanf ("%d", &a[i]); for (i=1;i<=m;i++) {scanf ("%d%d", &Q[I].L,&Q[I].R); Points[i].x=q[i].l;points[i].y=q[i].r;points[i].pos=i;} points[0].x=points[0].y=0x3f3f3f3f; Calculate (); for (i=1;i<=m;i++) points[i].y=-points[i].y; Calculate (); for (i=1;i<=m;i++) Points[i].y=-points[i].y,swap (POINTS[I].X,POINTS[I].Y); Calculate (); for (i=1;i<=m;i++) points[i].y=-points[i].y; Calculate (); Kruskal ();D FS (1,0), for (i=1;i<=m;i++) printf ("%u/%u\n", Ans[i].first,ans[i].second);}
Bzoj 2038 2009 Country Training Team Small Z socks (hose) MO Team Algorithm