【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 }

 

posted @ 2017-06-07 22:00  Kirai  阅读(200)  评论(0编辑  收藏  举报