【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
", 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.
", (int)clock());
241     #endif
242 
243     return 0;
244 }
原文地址:https://www.cnblogs.com/bombe1013/p/5170993.html