标签:
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> 10 #include <queue> 11 #include <assert.h> 12 #include <map> 13 14 const int N = 100000 + 10; 15 using namespace std; 16 int n, c, data[N]; 17 int SIZE; 18 map<int, int>color[334]; 19 20 void change2(int l,int r){ 21 int x = l / SIZE; 22 if(color[x].size() == 1){//整个块只有一个颜色 23 map<int, int>::iterator it = color[x].begin(); 24 int last = it->first, cnt = it->second; 25 if(c == last) return ;//显然等于原来的颜色就没必要修改了 26 if(r - l + 1 == cnt){//整个块都修改 27 color[x][c] = r - l + 1; 28 color[x].erase(it); 29 return; 30 } 31 for(int i = SIZE * x; i < n && i < SIZE * ( x + 1 ); i++){ 32 if(i >= l && i <= r) data[i] = c; 33 else data[i] = last; 34 } 35 color[x][c] = r - l + 1; 36 color[x][last] = cnt - (r - l + 1); 37 }else 38 for(int i = l; i <= r; i++) {//进行直接修改 39 if(data[i] == c) continue; 40 map<int, int>::iterator it = color[x].find(data[i]); 41 if(it->second == 1) color[x].erase(it);//记住一定要删除不然会超空间 42 else it->second--; 43 color[x][c]++; 44 data[i] = c; 45 } 46 } 47 //注意这种带2的操作是在同一个块内操作的 48 int query2(int l,int r){ 49 int x = l / SIZE; 50 if(color[x].count(c)){ 51 if(color[x].size() == 1) return r - l + 1;//整块的颜色唯一 52 else{ 53 int cnt = 0; 54 for(int i = l; i <= r; i++) if(data[i] == c) cnt++; 55 return cnt; 56 } 57 } else return 0; 58 } 59 60 void change(int l,int r){ 61 int x1 = l / SIZE, x2 = r / SIZE; 62 if(x1 == x2){change2(l, r);return;} 63 change2(l, SIZE * (x1 + 1) - 1); 64 change2(SIZE * x2, r); 65 //真正无奈 66 for(int i = x1 + 1; i < x2; i++){ 67 color[i].clear(); 68 color[i][c] = SIZE; 69 } 70 } 71 72 int query(int l,int r){ 73 int x1 = l / SIZE, x2 = r / SIZE; 74 if(x1 == x2) return query2(l,r); 75 int Ans = query2(l, SIZE * (x1 + 1) - 1) + query2(SIZE * x2 ,r); 76 for(int i = x1 + 1;i < x2;i++) 77 if(color[i].count(c)) Ans += color[i][c]; 78 return Ans; 79 } 80 81 void init(){ 82 SIZE = (int)sqrt(n * 1.0); 83 for(int i = 0; i < n; i++) scanf("%d", &data[i]); 84 for(int i = 0; i <= n / SIZE; i++) color[i].clear(); 85 for(int i = 0; i < n; i++) { 86 int tmp = i / SIZE; 87 color[tmp][ data[i] ]++; 88 } 89 } 90 91 int main(){ 92 #ifdef LOCAL 93 freopen("data.txt", "r", stdin); 94 freopen("out.txt", "w", stdout); 95 #endif 96 int m; 97 while(scanf("%d%d",&n,&m) != EOF){ 98 init(); 99 for (int i = 1; i <= m; i++){ 100 int t, l, r; 101 scanf("%d%d%d%d", &t, &l, &r, &c); 102 if(t == 1) change(l,r); 103 else printf("%d\n",query(l,r)); 104 } 105 } 106 return 0; 107 }
标签:
原文地址:http://www.cnblogs.com/hoskey/p/4322726.html