【HDOJ】4056 Draw a Mess
这题用线段树就MLE。思路是逆向思维,然后每染色一段就利用并查集将该段移除,均摊复杂度为O(n*m)。
1 /* 4056 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 typedef struct { 44 int id; 45 int xc, yc, w, h, c; 46 } draw_t; 47 48 const int maxm = 50005; 49 const int maxn = 205; 50 int fa[maxn][maxm]; 51 draw_t draw[maxm]; 52 int C[10]; 53 int n, m, q; 54 int xc, yc, w, h, c; 55 56 int find(int rn, int x) { 57 if (fa[rn][x] == x) 58 return x; 59 return fa[rn][x] = find(rn, fa[rn][x]); 60 } 61 62 void init() { 63 memset(C, 0, sizeof(C)); 64 rep(i, 0, n) 65 rep(j, 0, m+1) 66 fa[i][j] = j; 67 --n; 68 --m; 69 } 70 71 int move(int xth, int l, int r) { 72 int ret = 0; 73 74 l = find(xth, l); 75 while (l <= r) { 76 ++ret; 77 fa[xth][l] = l + 1; 78 l = find(xth, l+1); 79 } 80 81 return ret; 82 } 83 84 void DrawDiamond() { 85 int ly = yc - w; 86 int ry = yc + w; 87 int l, r, xth; 88 89 xth = xc; 90 while (xth>=0 && ly<=ry) { 91 l = max(0, ly); 92 r = min(m, ry); 93 C[c] += move(xth, l, r); 94 --xth; 95 ++ly; 96 --ry; 97 } 98 99 xth = xc + 1; 100 ly = yc - w + 1; 101 ry = yc + w - 1; 102 while (xth<=n && ly<=ry) { 103 l = max(0, ly); 104 r = min(m, ry); 105 C[c] += move(xth, l, r); 106 ++xth; 107 ++ly; 108 --ry; 109 } 110 } 111 112 void DrawRectangle() { 113 int xth = xc; 114 int n_ = min(n, xc+h-1); 115 int l = yc; 116 int r = min(m, yc+w-1); 117 118 while (xth <= n_) { 119 C[c] += move(xth, l, r); 120 ++xth; 121 } 122 } 123 124 void DrawTriangle() { 125 int w_ = w >> 1; 126 int n_ = min(n, xc+w_); 127 int ly = yc - w_; 128 int ry = yc + w_; 129 int l, r; 130 int xth = xc; 131 132 while (xth<=n_ && ly<=ry) { 133 l = max(0, ly); 134 r = min(m, ry); 135 C[c] += move(xth, l, r); 136 ++ly; 137 --ry; 138 ++xth; 139 } 140 } 141 142 void DrawCircle() { 143 int ly = yc - w; 144 int ry = yc + w; 145 int l, r; 146 __int64 w2 = 1LL * w * w, tmp; 147 int delta; 148 int xth = xc; 149 150 l = max(0, ly); 151 r = min(m, ry); 152 C[c] += move(xth, l, r); 153 154 rep(i, 1, w+1) { 155 tmp = 1LL * i * i; 156 delta = sqrt(w2 - tmp + 0.5); 157 ly = yc - delta; 158 ry = yc + delta; 159 l = max(0, ly); 160 r = min(m, ry); 161 if (xth-i >= 0) { 162 C[c] += move(xth-i, l, r); 163 } 164 if (xth+i <= n) { 165 C[c] += move(xth+i, l, r); 166 } 167 } 168 } 169 170 void solve() { 171 int id; 172 173 per(i, 0, q) { 174 id = draw[i].id; 175 xc = draw[i].xc; 176 yc = draw[i].yc; 177 w = draw[i].w; 178 c = draw[i].c; 179 h = draw[i].h; 180 if (id == 0) { 181 DrawCircle(); 182 } else if (id == 1) { 183 DrawDiamond(); 184 } else if (id == 2) { 185 DrawRectangle(); 186 } else { 187 DrawTriangle(); 188 } 189 } 190 191 rep(j, 1, 10) { 192 if (j == 9) { 193 printf("%d\n", C[j]); 194 } else { 195 printf("%d ", C[j]); 196 } 197 } 198 } 199 200 int main() { 201 ios::sync_with_stdio(false); 202 #ifndef ONLINE_JUDGE 203 freopen("data.in", "r", stdin); 204 freopen("data.out", "w", stdout); 205 #endif 206 207 char op[20]; 208 209 while (scanf("%d %d %d", &n, &m, &q)!=EOF) { 210 init(); 211 rep(i, 0, q) { 212 scanf("%s", op); 213 if (op[0] == 'C') { 214 scanf("%d %d %d %d", &xc, &yc, &w, &c); 215 draw[i].id = 0; 216 // DrawCircle(); 217 } else if (op[0] == 'D') { 218 scanf("%d %d %d %d", &xc, &yc, &w, &c); 219 draw[i].id = 1; 220 // DrawDiamond(); 221 } else if (op[0] == 'R') { 222 scanf("%d %d %d %d %d", &xc, &yc, &h, &w, &c); 223 draw[i].id = 2; 224 // DrawRectangle(); 225 } else { 226 scanf("%d %d %d %d", &xc, &yc, &w, &c); 227 draw[i].id = 3; 228 // DrawTriangle(); 229 } 230 draw[i].xc = xc; 231 draw[i].yc = yc; 232 draw[i].h = h; 233 draw[i].w = w; 234 draw[i].c = c; 235 } 236 solve(); 237 } 238 239 #ifndef ONLINE_JUDGE 240 printf("time = %d.\n", (int)clock()); 241 #endif 242 243 return 0; 244 }