【Unsolved】[HDOJ4391]Paint The Wall(分块,线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4391
题意:初始n个点有不同颜色,两种操作:1:区间染色,2:问区间内某个颜色的出现次数。
线段树维护点,在此基础上分块,发现应该是卡了线段树的log了。在想办法优化掉。
TLE代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define lrt rt << 1 5 #define rrt rt << 1 | 1 6 const int maxn = 100100; 7 typedef struct Seg { 8 int v[maxn<<4]; 9 Seg() { memset(v, -1, sizeof(v)); } 10 11 void pushdown(int rt) { 12 if(v[rt] == -1) return; 13 v[lrt] = v[rrt] = v[rt]; 14 v[rt] = -1; 15 } 16 17 int query(int pos, int l, int r, int rt) { 18 if(l == r) return v[rt]; 19 pushdown(rt); 20 int mid = (l + r) >> 1; 21 if(pos <= mid) return query(pos, l, mid, lrt); 22 else return query(pos, mid+1, r, rrt); 23 } 24 25 void update(int L, int R, int c, int l, int r, int rt) { 26 if(L <= l && r <= R) { 27 v[rt] = c; 28 return; 29 } 30 pushdown(rt); 31 int mid = (l + r) >> 1; 32 if(L <= mid) update(L, R, c, l, mid, lrt); 33 if(mid < R) update(L, R, c, mid+1, r, rrt); 34 } 35 }Seg; 36 37 int n, q, sz, be[maxn]; 38 map<int, int> block[maxn]; 39 Seg seg; 40 41 int query(int l, int r, int v) { 42 map<int, int> tmp; 43 int ret = 0; 44 for(int i = l; i <= r; ) { 45 if(i % sz == 0 && i + sz <= r) { 46 ret += block[be[i]][v]; 47 i += sz; 48 } 49 else { 50 ret += (v == seg.query(i+1, 1, n, 1)); 51 i++; 52 } 53 } 54 return ret; 55 } 56 57 void update(int l, int r, int v) { 58 for(int i = l; i <= r; ) { 59 if(i % sz == 0 && i + sz <= r) { 60 block[be[i]].clear(); block[be[i]][v] = sz; 61 seg.update(i+1, i+sz, v, 1, n, 1); 62 i += sz; 63 } 64 else { 65 int pre = seg.query(i+1, 1, n, 1); 66 seg.update(i+1, i+1, v, 1, n, 1); 67 block[be[i]][pre]--; block[be[i]][v]++; 68 i++; 69 } 70 } 71 } 72 73 int main() { 74 // freopen("in", "r", stdin); 75 int cmd, l, r, z; 76 while(~scanf("%d%d",&n, &q)) { 77 memset(seg.v, 0, sizeof(seg.v)); 78 for(int i = 0; i <= n; i++) block[i].clear(); 79 sz = sqrt(n); 80 for(int i = 0; i < n; i++) { 81 scanf("%d", &z); 82 be[i] = i / sz; 83 block[be[i]][z]++; 84 seg.update(i+1, i+1, z, 1, n, 1); 85 } 86 while(q--) { 87 scanf("%d%d%d%d",&cmd,&l,&r,&z); 88 if(cmd == 1) update(l, r, z); 89 else printf("%d\n", query(l, r, z)); 90 } 91 } 92 return 0; 93 }