Chunking algorithm
----------------------------------------------------------
1. Thought
If we need to operate on a particular sequence, then a very intuitive and simple method is pure violence (no, that's called impersonation).
But if the violence can be too, then hehe.
So we're going to think of some relatively high-energy data structures--chunking.
Compared to the segment tree, the block algorithm is difficult to achieve, but as long as the deep understanding, it can be achieved, but need some data structure of the auxiliary.
Chunking is essentially the segmentation of a sequence, which enables efficient processing of queries, lookups, replacements, and so on.
----------------------------------------------------------
2. Auxiliary structure
We know that the single-point query time for an array is O (1), and the insertion is O (n)
the single-point query time of the linked list is O (n), and the insertion is O (1)
In Noip, vectors are generally faster than arrays, so we can use vectors to store each piece, but if it is used to insert the vector, then the time will be unreasonable.
If we insert, we can use the pair
Usually to define these two data structures, simple words that pair will not be used, which should be defined according to test instructions.
----------------------------------------------------------
3. Templates
Action: Building Blocks (Rebuild)
Note: It is not necessary to build blocks at the beginning, but to block the sequence in the process
Purpose: When the current block is too large, you can use this function to split a chunk
void Rebuild () { top=0; for (int. i=1;i<=m;i++) {for (Vector<int>::iterator j=ve[i].begin (); J!=ve[i].end (); j + +) St [++top]=*j; Ve[i].clear ();//empty current block } int blo2=sqrt (top); for (int i=1;i<=top;i++) ve[(i-1)/blo2+1].push_back (St[i]); M= (top-1)/blo2+1;}
Operation: interval addition (ADD)
Note: Blo is an important variable of the block, is the root of n, you can think carefully why
Purpose: Can be used when the operation interval addition is required
void Add (int a,int b,int c) {for (int i=a;i<=min (BL[A]*BLO,B); i++) v[i]+=c,sum[bl[a]]+=c;; if (Bl[a]!=bl[b]) for (int i= (bl[b]-1) *blo+1;i<=b;i++) v[i]+=c,sum[bl[b]]+=c; for (int i=bl[a]+1;i<=bl[b]-1;i++) atag[i]+=c;}
Action: Insert
Note: You can control the size of the block
Purpose: inserting elements
void Insert (int a,int b) { pair<int,int> t=query (a); Ve[t.first].insert (Ve[t.first].begin () +t.second,b); if (Ve[t.first].size () >20*blo)//split chunk rebuild ();}
Common chunking only these few operations, more operations visible hzwer
"Fast processing" chunking algorithm