Title Link: http://acm.hdu.edu.cn/showproblem.php?pid=4391
Test instructions
Give an interval, there are two kinds of operation
1: The interval of x to Y is dyed as Z
2: Query the number of color z in the range x to Y
Ideas:
The z maximum 2^31-1 of the problem, the interval length of the maximum 1e5, with the line-tree color discretization after the maintenance will not survive
so with a chunked hash, a length of n is divided into sqrt (n) block maintenance, each block with a map to record the number of certain colors
chunked Hash:
Modify, query an interval, for the full coverage of the interval, can be quickly modified and queried
The range of incomplete coverage is at most only two, and can be modified in a violent
Create a struct hashblock, where the record itself length, coverage flag, initialized to-1 (represents not fully covered)
Determine the interval of length n, each length is Len, so it is divided into tot = (n-1)/s + 1 block
Special is the last paragraph length is min (n, (TOT) * len)-(tot-1) * len
Modifying an interval L, r, makes La = L/len, RA = R/len, from block [La+1, RA] are fully covered and can be updated directly
The sections [L, (L/len + 1) * Len] and [R] Len, R] may not be fully covered and need to be updated manually
I told the details so much to remind myself that the details can not be said, please read the code
First write chunked hash code, refer to Cxlove, thank
#include <cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<map>using namespacestd;Const intMAXN = 1e5+Ten;structhashblock{intSizee, color; Map<int,int>m;} block[333];intC[MAXN];intLen;intN;voidInit () {len= (int) sqrt (n); inttot = (N-1)/Len +1; for(inti =0; i < tot; i++) {Block[i].sizee= Min (n, (i+1) * len)-I *Len; Block[i].color= -1; Block[i].m.clear (); }}//If an interval is to be updated manually, you need to overwrite the color of the last block update before manually updating//similar to pushdown in segment treevoidPushdown (intStep) { if(Block[step].color! =-1) {block[step].m.clear (); for(inti = step * len; I < n && i < (step+1) * LEN; i++) {C[i]=Block[step].color; Block[step].m[c[i]]++; } Block[step].color= -1; }}voidUpdate (intLintRintcolor) { intLa = L/len, RA = r/Len; //full coverage of the range can be updated directly for(inti = La +1; i < RA; i++) {Block[i].color=color; } //parts of a violent update that are not fully covered if(La! =RA) {Pushdown (LA), Pushdown (RA); for(inti = l; I < (la+1) * LEN; i++) {Block[la].m[c[i]]--, block[la].m[color]++, c[i] =color; } for(inti = ra * len; I <= R; i++) {Block[ra].m[c[i]]--, block[ra].m[color]++, c[i] =color; } } Else{//It's the same interval .pushdown (LA); for(inti = l; I <=r; i++) {Block[la].m[c[i]]--, block[la].m[color]++, c[i] =color; } }}intQuery (intLintRintcolor) { intAns =0; intLa = L/len, RA = r/Len; for(inti = La +1; i < RA; i++) { if(Block[i].color = = color) ans + =Block[i].sizee; Else if(Block[i].color = =-1&&block[i].m.find (color)!=Block[i].m.end ()) {ans+=Block[i].m[color]; } } if(La! =RA) {Pushdown (LA), Pushdown (RA); for(inti = l; I < (la+1) * LEN; i++) {ans+ = C[i] = =color; } for(inti = ra * len; I <= R; i++) {ans+ = C[i] = =color; } } Else{pushdown (LA); for(inti = l; I <=r; i++) {ans+ = C[i] = =color; } } returnans;}intMain () {intQ; while(SCANF ("%d%d", &n, &q)! =EOF) {Init (); for(inti =0; I < n; i++) {scanf ("%d", &C[i]); Block[i/len].m[c[i]]++; } while(q--) { intcmd, l, R, Z; scanf ("%d %d%d%d", &cmd, &l, &r, &z); if(cmd = =1) Update (l, R, Z); Elseprintf"%d\n", Query (l, R, Z)); } } return 0;}
View Code
HDU 4391-paint The Wall-Getting started with chunked hashing