Hướng dẫn giải của Chu vi các hình chữ nhật
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của flashmt
uses math; const fi=''; fo=''; maxn=10010; type ar=array[1..maxn*2] of longint; var n,nh,nv:longint; re:int64; x,y,h,v,d,e,xx,yy,xt,yt:ar; a:array[1..maxn*9] of longint; s:array[1..maxn*9] of int64; procedure rf; var i:longint; begin read(n); for i:=1 to n do read(x[i*2-1],y[i*2-1],x[i*2],y[i*2]); for i:=1 to n*2 do begin xt[i]:=x[i]; yt[i]:=y[i]; h[i]:=y[i]; v[i]:=x[i]; d[i]:=i; e[i]:=i; end; end; procedure mark; var i:longint; begin for i:=1 to n do begin xx[i*2-1]:=x[i*2]; xx[i*2]:=x[i*2-1]; end; for i:=1 to n*2 do begin h[i]:=y[i]; v[i]:=x[i]; d[i]:=i; e[i]:=i; end; end; procedure sort(var h,d:ar;l,r:longint); var i,j,x,y,t:longint; begin i:=l; j:=r; x:=h[(i+j) shr 1]; y:=d[(i+j) shr 1] and 1; repeat while (h[i]<x) or ((h[i]=x) and (d[i] and 1>y)) do inc(i); while (h[j]>x) or ((h[j]=x) and (d[j] and 1<y)) do dec(j); if i<=j then begin t:=h[i]; h[i]:=h[j]; h[j]:=t; t:=d[i]; d[i]:=d[j]; d[j]:=t; inc(i); dec(j); end; until i>j; if i<r then sort(h,d,i,r); if l<j then sort(h,d,l,j); end; procedure roirac; var i:longint; begin sort(h,d,1,n*2); nh:=1; y[d[1]]:=1; for i:=2 to n*2 do begin if h[i]<>h[nh] then begin inc(nh); h[nh]:=h[i]; end; y[d[i]]:=nh; end; for i:=1 to n do dec(y[i*2]); for i:=1 to n do begin yy[i*2-1]:=y[i*2]; yy[i*2]:=y[i*2-1]; end; end; procedure add(node,l,r,x,y,val:longint); var mid:longint; begin if (l=x) and (r=y) then begin a[node]:=a[node]+val; if a[node]=1 then s[node]:=h[r+1]-h[l]; if a[node]=0 then begin if l<r then s[node]:=s[node shl 1]+s[node shl 1+1] else s[node]:=0; end; end else begin mid:=(l+r) shr 1; if x<=mid then add(node shl 1,l,mid,x,min(y,mid),val); if y>mid then add(node shl 1+1,mid+1,r,max(x,mid+1),y,val); if a[node]=0 then s[node]:=s[node shl 1]+s[node shl 1+1]; end; end; procedure pr; var i,t,last:longint; begin roirac; sort(v,e,1,n*2); last:=0; for i:=1 to n*2 do begin t:=e[i]; if xx[t]>x[t] then add(1,1,n*2-1,y[t],yy[t],1) else add(1,1,n*2-1,yy[t],y[t],-1); re:=re+abs(s[1]-last); last:=s[1]; end; end; procedure rotate; var i:longint; begin for i:=1 to n*2 do begin x[i]:=yt[i]; y[i]:=xt[i]; end; fillchar(d,sizeof(d),0); fillchar(e,sizeof(e),0); fillchar(xx,sizeof(xx),0); fillchar(yy,sizeof(yy),0); fillchar(h,sizeof(h),0); fillchar(v,sizeof(v),0); fillchar(s,sizeof(s),0); fillchar(a,sizeof(a),0); nh:=0; nv:=0; end; begin assign(input,fi); reset(input); rf; mark; pr; rotate; mark; pr; writeln(re); close(input); end.
Code mẫu của ladpro98
#include <cstring> #include <vector> #include <list> #include <map> #include <set> #include <queue> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <climits> #include <cstdlib> #include <ctime> #include <memory.h> #include <cassert> #include <climits> #define FOR(i, a, b) for(int i = (a); i < (b); i++) #define REP(i, a, b) for(int i = (a); i <=(b); i++) #define FORD(i, a, b) for(int i = (a); i > (b); i--) #define REPD(i, a, b) for(int i = (a); i >=(b); i--) #define TR(it, a) for(typeof((a).begin()) it = (a).begin(); it != (a).end(); it++) #define RESET(a, v) memset((a), (v), sizeof((a))) #define SZ(a) (int((a).size())) #define ALL(a) (a).begin(), (a).end() #define PB push_back #define MP make_pair #define LL long long #define LD long double #define II pair<int, int> #define X first #define Y second #define VI vector<int> const int N = 33333; const int M = 4 * N; int OPEN = 1; int CLOSE = -1; using namespace std; typedef pair<int, int> point; typedef pair<point, point> rectangle; struct event { int x, l, r, type; event(int _x, int _l, int _r, int _t) { x = _x; l = _l; r = _r; type = _t; } bool operator < (const event &that) const{ return x < that.x; } }; II Min(const II &a, const II &b) { if (a.X != b.X) return min(a, b); return MP(a.X, a.Y + b.Y); } int delay[M]; II MIN[M]; #define ll (id << 1) #define rr (ll | 1) struct node { int l, r, id; void access() { if (delay[id] == 0) return; MIN[id].X += delay[id]; if (l != r) { delay[ll] += delay[id]; delay[rr] += delay[id]; } delay[id] = 0; } node(int _l, int _r, int _id) {l = _l; r = _r; id = _id; access();} node left() {return node(l, l + r >> 1, ll);} node right() {return node((l + r >> 1) + 1, r, rr);} void build() { if (l > r) return; if (l == r) {MIN[id] = MP(0, 1); return;} left().build(); right().build(); MIN[id] = Min(MIN[ll], MIN[rr]); } void incRange(int i, int j, int v) { if (l > r || r < i || j < l) return; if (i <= l && r <= j) { delay[id] += v; access(); return; } left().incRange(i, j, v); right().incRange(i, j, v); MIN[id] = Min(MIN[ll], MIN[rr]); } II getMin(int i, int j) { if (l > r || r < i || j < l) return MP(INT_MAX, 0); if (i <= l && r <= j) return MIN[id]; return Min(left().getMin(i, j), right().getMin(i, j)); } }; rectangle rect[N]; vector<event> e; int n, ans; void initEvents() { e.clear(); FOR(i, 0, n) { e.PB(event(rect[i].X.X, rect[i].X.Y, rect[i].Y.Y, OPEN)); e.PB(event(rect[i].Y.X, rect[i].X.Y, rect[i].Y.Y, CLOSE)); } sort(ALL(e)); } void sweepLine() { node root(0, N - 1, 1); root.build(); FOR(step, 0, 2) { int j = 0; for(int i = 0; i < SZ(e); i = j + 1) { j = i; while (j + 1 < SZ(e) && e[j + 1].x == e[i].x) j++; vector<II> ranges; REP(k, i, j) if (e[k].type == CLOSE) ranges.PB(MP(e[k].l, e[k].r - 1)); REP(k, i, j) root.incRange(e[k].l, e[k].r - 1, step ? -e[k].type : (e[k].type)); if (!ranges.empty()) { sort(ALL(ranges)); int maxR = ranges[0].Y; II tmp = root.getMin(ranges[0].X, ranges[0].Y); if (tmp.X == 0) ans += tmp.Y; FOR(k, 1, SZ(ranges)) { int l = ranges[k].X, r = ranges[k].Y; if (maxR >= l) l = maxR + 1; if (l > r) continue; tmp = root.getMin(l, r); if (tmp.X == 0) ans += tmp.Y; maxR = max(maxR, r); } } } reverse(ALL(e)); swap(OPEN, CLOSE); } } void process() { initEvents(); sweepLine(); } void testSegmentTree() { const int ADD = 0; const int GET = 1; int i, j, v, queryType; while (cin >> i >> j >> v) { node(0, N - 1, 1).incRange(i, j, v); FOR(i, 0, 10) cout << node(0, N - 1, 1).getMin(i, i).X << ' '; cout << endl; } } int main() { ios :: sync_with_stdio(0); cin.tie(0); cin >> n; FOR(i, 0, n) cin >> rect[i].X.X >> rect[i].X.Y >> rect[i].Y.X >> rect[i].Y.Y; process(); FOR(i, 0, n) swap(rect[i].X.X, rect[i].X.Y), swap(rect[i].Y.X, rect[i].Y.Y); process(); cout << ans; return 0; }
Code mẫu của RR
//Wishing myself a happy lunar new year with a lot of accept solutions //Written by Nguyen Thanh Trung {$R+,Q+} uses math; const FINP=''; FOUT=''; MAXN=10001; snode=131072; var f1,f2:text; nn,n,sum:longint; rect:array[1..MAXN] of record x1,y1,x2,y2:longint; end; c,x1,x2,y,typ:array[1..MAXN*2] of longint; left,right,all,sl:array[1..snode] of longint; procedure openF; inline; begin assign(f1,FINP); reset(f1); assign(f2,FOUT); rewrite(f2); end; procedure closeF; inline; begin close(f1); close(f2); end; procedure inp; inline; begin read(f1,n); for n:=1 to n do with rect[n] do read(f1,x1,y1,x2,y2); end; var temp:longint; procedure swap(var a,b:longint); inline; begin temp:=a; a:=b; b:=temp; end; var mid:longint; procedure sortC(l,r:longint); inline; var i,j:longint; begin i:=l; j:=r; mid:=c[l+random(r-l+1)]; repeat while c[i]<mid do inc(i); while c[j]>mid do dec(j); if i<=j then begin swap(c[i],c[j]); inc(i); dec(j); end; until i>j; if i<r then sortC(i,r); if l<j then sortC(l,j); end; procedure makeC; inline; var i:longint; begin nn:=0; for i:=1 to n do begin inc(nn); c[nn]:=rect[i].x1; inc(nn); c[nn]:=rect[i].x2; end; sortC(1,nn); i:=1; for nn:=1 to nn do if c[nn]>c[i] then begin inc(i); c[i]:=c[nn]; end; nn:=i; end; procedure sortH(l,r:longint); inline; var i,j:longint; begin i:=l; j:=r; mid:=y[l+random(r-l+1)]; repeat while y[i]<mid do inc(i); while y[j]>mid do dec(j); if i<=j then begin swap(x1[i],x1[j]); swap(x2[i],x2[j]); swap(y[i],y[j]); swap(typ[i],typ[j]); inc(i); dec(j); end; until i>j; if i<r then sortH(i,r); if l<j then sortH(l,j); end; procedure makeH; inline; var i:longint; begin i:=0; for n:=1 to n do begin inc(i); x1[i]:=rect[n].x1; x2[i]:=rect[n].x2; y[i]:=rect[n].y1; typ[i]:=1; inc(i); x1[i]:=rect[n].x1; x2[i]:=rect[n].x2; y[i]:=rect[n].y2; typ[i]:=-1; end; sortH(1,i); end; procedure init; begin fillchar(all,sizeof(all),0); fillchar(sl,sizeof(sl),0); end; procedure update(u,v,k:longint); procedure visit(i,l,r:longint); inline; var mid:longint; begin if (v<=c[l]) or (c[r+1]<=u) or (l>r) then exit; if (u<=c[l]) and (c[r+1]<=v) then begin all[i]:=all[i]+k; if all[i]>0 then begin sl[i]:=1; right[i]:=1; left[i]:=1; end else begin left[i]:=left[i<<1]; right[i]:=right[i<<1+1]; sl[i]:=sl[i<<1]+sl[i<<1+1]; if right[i<<1]+left[i<<1+1]=2 then dec(sl[i]); end; exit; end; mid:=(l+r)>>1; visit(i<<1,l,mid); visit(i<<1+1,mid+1,r); if all[i]>0 then begin sl[i]:=1; right[i]:=1; left[i]:=1; end else begin left[i]:=left[i<<1]; right[i]:=right[i<<1+1]; sl[i]:=sl[i<<1]+sl[i<<1+1]; if right[i<<1]+left[i<<1+1]=2 then dec(sl[i]); end; end; begin visit(1,1,nn-1); end; procedure solve; inline; var i:longint; begin makeC; makeH; for i:=1 to 2*n do begin if sl[1]>0 then sum+=(y[i]-y[i-1])*sl[1]; update(x1[i],x2[i],typ[i]); end; end; procedure reverse; inline; begin for n:=1 to n do with rect[n] do begin swap(x1,y1); swap(x2,y2); end; end; procedure ans; inline; begin writeln(f2,sum<<1); end; begin openF; inp; sum:=0; solve; init; reverse; solve; ans; closeF; end.
Bình luận