"Algorithm One"
Violence.
Can pass the No. 0,1 test point.
Estimated score: a score of.
"Algorithm Two"
Classic question: Interval number, data range is not very large, so we can:
① block, discretization, preprocessing:
The number of x occurrences in the <1> front i block ( differential );
<2> number of people in block I to block J is who, how many times have appeared.
When asked, the answer to the whole block is directly answered; for scattered parts, the number of occurrences of each number of violent statistics, coupled with the result of differential, attempts to update ans.
Time Complexity O (M*SQRT (n)),
Space complexity O (N*SQRT (n)).
② consider offline, MO team algorithm, transfer when using data structure maintenance, concrete implementation does not repeat.
Time Complexity O (M*SQRT (n) *log (n)),
Space complexity O (n).
Combined algorithm One, the expected score : a score of.
"Algorithm three"
Consider offline, the MO team algorithm, store an array, record the number of occurrences of the weights, and then we insert these times into a weight block Which is a data structure for weight-value chunking, which is characterized by supporting o (1) o (sqrt (n)) k big, global rank, precursor, successor, and so can be good with the team algorithm to solve the non-modified interval query ) o (1) o (sqrt (n)) to realize the inquiry. But we also need to know k2 small value, So at each node of the weight block, maintaining a balanced tree, the insertion time complexity becomes higher.
Time Complexity O (M*SQRT (n) *log (n ) ( Insert, delete ) +m*sqrt (n) ( query ))
Space complexity O (n).
Can be 0,1,2 (?) , 3 (?) , 4 , 5 test point.
Estimated score: up to ~60 points, combined with the algorithm two can be obtained , may need constant optimization.
"Algorithm Four"
We found that the main problem with algorithm three is that the insertion into the balance tree is O (logn) So if we replace the balance tree with the weights, we can implement the inserted, without affecting the complexity of the query.
However, the size of the sub-weights of each node is strictly a range of values, that is, the number of occurrences may be I can be in that sub-weight of the block. So our space is unbearable. Therefore, we need to do "piecewise discretization"( to the number of occurrences i, to the occurrence of the number of >=i The weight of the value of all discrete. This is done for each I ) ( The complexity is proven later ).
The data structure we ultimately need is this:
An array of pinlv[], recording the number of occurrences of each weight value;
A weighted block block[], maintaining the number of occurrences;
Then in the above the weight of each node of the block and then open a sub-weight value of the block, record the number of occurrences of its weight is what kinds.
A bit around is not ... As an example:
n=11
2 1 3 2 1 4 1 2 2 1 4
Suppose the current data structure is maintaining a1...an interval.
Array PINLV |
[1] |
[2] |
[3] |
[4] |
|
4 |
4 |
1 |
2 |
Block of weights |
[1] |
[2] |
[3] |
[4] |
|
1 |
1 |
0 |
2 |
Sub-weight value sub-block |
3 |
4 |
|
1 |
|
|
|
|
2 |
※ Some proofs of complexity:
Number of occurrences i |
1 |
2 |
3 |
4 |
5 |
... |
M |
Sum of the number of weights with occurrences of I ( with repetition ) |
S1 |
S2 |
S3 |
S4 |
S5 |
... |
Sm |
S1+s2+s3+...+sm=n (1<=m<=n) |
AI represents the number of weight types that occur in the number of i :
A1=s1
A2=s2/2
A3=s3/3
...
am=sm/m
Set P to be a suffix and:
P1=a1+a2+a3+a4+...+am
P2=a2+a3+a4...+am
P3=a3+a4...+am
...
Pm=am
Total space F for ① sub-weight block:
f=p1+p2+...+pm
=m*am+ (m-1) *am-1+...+2*a2+1*a1
=m*sm/m+ (m-1) *SM-1/M-1+...+1*S1/1
=s1+s2+s3+s4+...+sm
=n
② Total space F' of sub-weights with no fragmentation discretization:
F ' = (a1+a2+...+am) *n
Complexity is difficult to guarantee.
The total time complexity of ③ piecewise discretization g ( the log involved here is <=logn , so we use logn Replace ):
First, the original array is de-weighed, and its size becomes a 1+a2+...+am
G<=p1*logn+p2*logn+...+pm*logn
= (m*am+ (m-1) *am-1+...+2*a2+1*a1) *logn
= (m*sm/m+ (m-1) *SM-1/M-1+...+1*S1/1) *logn
= (S1+S2+S3+S4+...+SM) *logn
=n*logn
④ The total space H of the array that records the value of each weighted value discretization:
h=p1+p2+...+pm
=m*am+ (m-1) *am-1+...+2*a2+1*a1
=m*sm/m+ (m-1) *SM-1/M-1+...+1*S1/1
=s1+s2+s3+s4+...+sm
=n
So, in the end, as long as the vector is reasonably used, the spatial complexity of our algorithm is O (n),
The time complexity is O (M*SQRT (n)).
Estimated score: up to a point.
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector >using namespace std; #define MAXN 40001typedef vector<int>::iterator ver;int t[maxn],plt;int n,m,a[maxn],pl[ MAXN],UPD,NUM_MO[MAXN],ANSS[MAXN],NUM_PL[MAXN],L_PL[MAXN],S_PL[MAXN];VECTOR<INT>LISAN[MAXN],EVPL[MAXN], Evnum[maxn],evl[maxn],evs[maxn],evb[maxn];bool vis[maxn];struct ask{int l,r,k1,k2,p;} Q[maxn];bool operator < (const ask &a,const ask &b) {return NUM_MO[A.L]!=NUM_MO[B.L]? num_mo[a.l]<num_mo[b . l]: A.R<B.R;} void Mo_make_block () {int tot=1,sz=sqrt (n); if (!sz) sz=1; for (; tot*sz<n;++tot) {int r=tot*sz; for (int i= (tot-1) *sz+1;i<=r;++i) Num_mo[i]=tot; } for (int i= (tot-1) *sz+1;i<=n;++i) Num_mo[i]=tot;} void Pl_make_block () {plt=1;int sz=sqrt (UPD); if (!sz) sz=1; for (;p lt*sz<upd;++plt) {l_pl[plt]= (plt-1) *sz+1; int R=plt*sz; for (int i=l_pl[plt];i<=r;++i) NUM_PL[I]=PLT; } l_pl[plt]= (plt-1) *sz+1; for (int i=l_pl[plt];i<=upd;++i) NUM_PL[I]=PLT;} void Insert (const int &x) {if (t[x]) {--pl[t[x]];if (!pl[t[x])--s_pl[num_pl[t[x]]];--evb[t[x]][lisan[x][t[x]]];- -EVS[T[X]][EVNUM[T[X]][LISAN[X][T[X]]; }++t[x];if (!pl[t[x]) ++s_pl[num_pl[t[x]]];++pl[t[x]];++evb[t[x]][lisan[x][t[x]]];++evs[t[x]][evnum[t[x]][lisan [x] [T[x]]];} void Delete (const int &x) {--pl[t[x]];if (!pl[t[x]])--s_pl[num_pl[t[x]]];--evb[t[x]][lisan[x][t[x]]];--evs[t[x] ][evnum[t[x]][lisan[x][t[x]]]];--t[x];if (T[x]) {if (!pl[t[x]) ++s_pl[num_pl[t[x]]; ++PL[T[X]];++EVB[T[X]][LISAN[X][T[X]]];++EVS[T[X]][EVNUM[T[X]][LISAN[X][T[X]]; }}int Query (const int &k1,const int &k2) {int cnt1=0,cnt2=0;for (int i=1;; ++i) {Cnt1+=s_pl[i]; if (CNT1>=K1) {cnt1-=s_pl[i]; for (int j=l_pl[i];; ++J) {cnt1+= (bool) pl[j]; if (CNT1>=K1) {for (int k=1;; ++K) {cnt2+=evs[j][k]; if (CNT2>=K2) {cnt2-=EVS[J][K]; for (int l=evl[j][k];; ++L) {cnt2+=evb[j][l]; if (CNT2>=K2) return evpl[j][l]; }}}}}}}}int main () {scanf ("%d", &n); Mo_make_block (); for (int i=1;i<=n;++i) {scanf ("%d", &a[i]); ++pl[a[i]]; }upd=*max_element (pl+1,pl+n+1);p l_make_block (); for (int i=1;i<=n;++i) if (!vis[a[i]]) {vis[a[i]]=1; Lisan[a[i]].assign (pl[a[i]]+1,0); for (int j=1;j<=pl[a[i]];++j) Evpl[j].push_back (A[i]); }for (int i=1;i<=upd;++i) {//piecewise discretization sort (evpl[i].begin (), Evpl[i].end ()); int k=1; For (VER J=evpl[i].begin (); J!=evpl[i].end (); ++j,++k) lisan[*j][i]=k; Piecewise weights block int lim=evpl[i].size (); Evb[i].assign (lim+1,0); int tot=1,sz=sqrt (LIM); Evl[i].push_back (0); Evnum[i].push_back (0); if (!sz) sz=1; for (; tot*sz<lim;++tot) {Evl[i].push_back ((tot-1) *sz+1); int R=tot*sz; for (int j=eVL[I][TOT];J<=R;++J) Evnum[i].push_back (TOT); } evl[i].push_back ((tot-1) *sz+1); for (int j=evl[i][tot];j<=lim;++j) evnum[i].push_back (TOT); Evs[i].assign (tot+1,0); Evpl[i].insert (Evpl[i].begin (), 0); }SCANF ("%d", &m), for (int i=1;i<=m;++i) {scanf ("%d%d%d%d", &Q[I].L,&Q[I].R,&Q[I].K1,&Q[I].K2 ); Q[i].p=i; }sort (q+1,q+m+1); memset (pl,0, (n+1) *sizeof (int.)); for (int i=q[1].l;i<=q[1].r;++i) Insert (A[i]); Anss[q[1].p]=query (Q[1].K1,Q[1].K2); for (int i=2;i<=m;++i) {if (Q[I].L<Q[I-1].L) for (int j=q[i-1].l-1;j>=q[i].l;--j) Insert (A[j]); if (Q[I].R>Q[I-1].R) for (int j=q[i-1].r+1;j<=q[i].r;++j) Insert (A[j]); if (Q[I].L>Q[I-1].L) for (int j=q[i-1].l;j<q[i].l;++j) Delete (A[j]); if (Q[I].R<Q[I-1].R) for (int j=q[i-1].r;j>q[i].r;--j) Delete (A[j]); Anss[q[i].p]=query (Q[I].K1,Q[I].K2); } for (int i=1;i<=m;++i) printf ("%d\n", Anss[i]); return 0;}
"Mo Team Algorithm" "Weight value chunking" bzoj3920 Yuuna Gift