Problem Descriptionas a amateur artist, Xenocide loves painting the wall. The wall can considered as a line consisting of n nodes. Each node have its own color.
Xenocide spends all day in front of the wall. Sometimes, he paints some consecutive nodes so, these nodes has the same color. When he feels tired, he focuses on a particular color and counts the number of nodes that has this color within a given I Nterval.
Now xenocide are tired of counting, so he turns to your for help.
Inputthe input consists of several test cases.
The first line of all test case contains-N, m (1<=n, m<=100000) indicating the length of the wall and th E Number of queries.
The following line contains N integers which describe the original color of every position.
Then M lines follow. Each line contains 4 non-negative integers a, l, R, Z (1<=a<=2, 0<=l<=r<n,
0<=z<231).
A = 1 indicates that xenocide paints nodes between L and r and the resulting color is Z.
A = 2 indicates that Xenocide wants to know how many nodes between L and R has the color Z. Outputprint the corresponding Answer for each queries. Sample INPUT5 2 3 4 Training 1 3 to 1 3, 1 3, 0 3, 3 4 1 Sample Output1041 Source2012 multi-university Contest 10 "Analyze" the bare topic of the Block list can also be done with a line tree. Remember in the map do not use the elements to erase off, or occupy space, will be super. Dizzy, engaged for 1.5 hours, t countless times, the back of the reference to other people's code ..., the same is the block list, the difference is so big (╯‵-′) ╯︵┻━┻.
1#include <iostream>2#include <cstdio>3#include <algorithm>4#include <cstring>5#include <vector>6#include <utility>7#include <iomanip>8#include <string>9#include <cmath>Ten#include <queue> One#include <assert.h> A#include <map> - - Const intN =100000+Ten; the using namespacestd; - intN, c, data[n]; - intSIZE; -map<int,int>color[334]; + - voidChange2 (intLintR) { + intx = L/SIZE; A if(color[x].size () = =1){//the whole block has only one color . atmap<int,int>::iterator it =Color[x].begin (); - intLast = It->first, cnt = it->second; - if(c = = last)return;//Obviously, it's not necessary to change the original color. - if(R-l +1= = cnt) {//the entire block is modified -COLOR[X][C] = r-l +1; - Color[x].erase (it); in return; - } to for(inti = SIZE * x; I < n && i < SIZE * (x +1); i++){ + if(I >= l && i <= r) data[i] =C; - ElseData[i] =Last ; the } *COLOR[X][C] = r-l +1; $Color[x][last] = cnt-(r-l +1);Panax Notoginseng}Else - for(inti = l; I <= R; i++) {//make a direct modification the if(Data[i] = = c)Continue; +map<int,int>::iterator it =Color[x].find (Data[i]); A if(It->second = =1) color[x].erase (it);//Remember to delete it or it will be hyperspace . the Elseit->second--; +color[x][c]++; -Data[i] =C; $ } $ } - //Note that this operation with 2 is done within the same block. - intQuery2 (intLintR) { the intx = L/SIZE; - if(Color[x].count (c)) {Wuyi if(color[x].size () = =1)returnR-l +1;//the color of the whole block is unique the Else{ - intCNT =0; Wu for(inti = l; I <= R; i++)if(Data[i] = = c) cnt++; - returnCNT; About } $}Else return 0; - } - - voidChangeintLintR) { A intx1 = l/size, x2 = r/SIZE; + if(x1 = = x2) {Change2 (L, R);return;} theChange2 (L, SIZE * (x1 +1) -1); -Change2 (SIZE *x2, R); $ //really helpless the for(inti = x1 +1; I < X2; i++){ the color[i].clear (); theCOLOR[I][C] =SIZE; the } - } in the intQueryintLintR) { the intx1 = l/size, x2 = r/SIZE; About if(x1 = = x2)returnQuery2 (l,r); the intAns = Query2 (L, SIZE * (x1 +1) -1) + Query2 (SIZE *x2, R); the for(inti = x1 +1; I < x2;i++) the if(Color[i].count (c)) Ans + =Color[i][c]; + returnAns; - } the Bayi voidinit () { theSIZE = (int) sqrt (n *1.0); the for(inti =0; I < n; i++) scanf ("%d", &data[i]); - for(inti =0; I <= n/size; i++) color[i].clear (); - for(inti =0; I < n; i++) { the intTMP = I/SIZE; thecolor[tmp][Data[i]]++; the } the } - the intMain () { the #ifdef LOCAL theFreopen ("Data.txt","R", stdin);94Freopen ("OUT.txt","W", stdout); the #endif the intm; the while(SCANF ("%d%d", &n,&m)! =EOF) { 98 init (); About for(inti =1; I <= m; i++){ - intT, L, R;101scanf"%d%d%d%d", &t, &l, &r, &c);102 if(T = =1) Change (l,r);103 Elseprintf"%d\n", Query (l,r));104 } the }106 return 0;107}
View Code
"HDU4391" "blocky list" Paint the Wall