Editorial for Diện tích hình chữ nhật
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
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,re:longint; x,y,h,v,d,e,xx,yy:ar; a,s:array[1..maxn*10] of longint; procedure rf; var i:longint; begin read(n); for i:=1 to n do begin read(x[i*2-1],y[i*2-1],x[i*2],y[i*2]); 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:longint; begin i:=l; j:=r; x:=h[(i+j) shr 1]; repeat while h[i]<x do inc(i); while h[j]>x do dec(j); if i<=j then begin y:=h[i]; h[i]:=h[j]; h[j]:=y; y:=d[i]; d[i]:=d[j]; d[j]:=y; 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[2*i]); 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:longint; begin roirac; sort(v,e,1,n*2); for i:=1 to n*2 do begin if i>1 then re:=re+(v[i]-v[i-1])*s[1]; 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); end; writeln(re); end; begin assign(input,fi); reset(input); rf; pr; close(input); end.
Code mẫu của ladpro98
#include <bits/stdc++.h> #define ii pair<int, int> #define iiii pair<pair<int, int> , pair<int, int> > #define X first #define Y second const int xxx = 33333; const int Open = 1; const int Close = -1; using namespace std; vector<iiii> event; ii it[8*xxx]; int n, res; void Enter() { //freopen("AREA.inp", "r", stdin); scanf("%d\n", &n); int i, x1, y2, x2, y1; for(i=1; i<=n; i++) { scanf("%d %d %d %d\n", &x1, &y1, &x2, &y2); event.push_back(iiii(ii(x1, Open), ii(y1, y2))); event.push_back(iiii(ii(x2, Close), ii(y1, y2))); } sort(event.begin(), event.end()); } void Upd(int k, int l, int r, int i, int j, int v) { if (r<=i || j<=l) return; if (i<=l && r<=j ) it[k].X += v; else { int m = (l+r) >> 1; Upd(k << 1, l, m, i, j, v); Upd((k << 1) | 1, m, r, i, j, v); } if (it[k].X == 0) it[k].Y = it[k << 1].Y + it[(k << 1) | 1].Y; else it[k].Y = r - l; } void SweepLine() { int i, y1, y2, type, len, d; for(i=0; i<(event.size()-1); i++) { y1 = event[i].Y.X; y2 = event[i].Y.Y; type = event[i].X.Y; Upd(1, 0, xxx, y1, y2, type); len = event[i+1].X.X - event[i].X.X; d = it[1].Y; res += len * d; } } int main() { Enter(); SweepLine(); printf("%d", res); return 0; }
Code mẫu của RR
uses math; var res,now,n,i,x1,y1,x2,y2,m:longint; sl,sum:array[1..131072] of longint; x,u,v,typ:array[1..20111] of longint; procedure swap(var a,b:longint); var tmp:longint; begin tmp:=a; a:=b; b:=tmp; end; procedure sort(l,r:longint); var i,j,mid:longint; begin i:=l; j:=r; mid:=x[l+random(r-l+1)]; repeat while x[i]<mid do inc(i); while x[j]>mid do dec(j); if i<=j then begin swap(x[i],x[j]); swap(u[i],u[j]); swap(v[i],v[j]); swap(typ[i],typ[j]); inc(i); dec(j); end; until i>j; if i<r then sort(i,r); if l<j then sort(l,j); end; procedure update(u,v,k,i,l,r:longint); var mid:longint; begin if (v<l) or (r<u) then exit; if (u<=l) and (r<=v) then begin inc(sl[i],k); if sl[i]>0 then sum[i]:=r-l+1 else sum[i]:=sum[i*2]+sum[i*2+1]; exit; end; mid:=(l+r) shr 1; update(u,v,k,i*2,l,mid); update(u,v,k,i*2+1,mid+1,r); if sl[i]=0 then sum[i]:=sum[i*2]+sum[i*2+1] else sum[i]:=r-l+1; end; begin read(n); m:=0; for i:=1 to n do begin read(x1,y1,x2,y2); inc(x1); inc(y1); inc(x2); inc(m); x[m]:=x1; u[m]:=y1; v[m]:=y2; typ[m]:=1; inc(m); x[m]:=x2; u[m]:=y1; v[m]:=y2; typ[m]:=-1; end; sort(1,m); now:=1; res:=0; for i:=1 to 30111 do begin while (x[now]=i) do begin update(u[now],v[now],typ[now],1,1,30111); inc(now); end; inc(res,sum[1]); end; writeln(res); end.
Code mẫu của ll931110
Program AREA; Const input = ''; output = ''; Type rec = record low: longint; high: longint; open: boolean; end; arr = array[1..200000] of longint; Var x,number,cover,c: arr; lab: array[1..200000] of rec; n: longint; S: int64; Procedure init; Var f: text; i: longint; x1,y1,x2,y2: longint; Begin Assign(f, input); Reset(f); Readln(f, n); For i:= 1 to n do Begin Read(f, x1, y1, x2, y2); x[2 * i - 1]:= x1; x[2 * i]:= x2; with lab[2 * i - 1] do Begin low:= y1; high:= y2; open:= true; End; with lab[2 * i] do Begin low:= y1; high:= y2; open:= false; End; c[2 * i - 1]:= y1; c[2 * i]:= y2; End; Close(f); Fillchar(number, sizeof(number), 0); Fillchar(cover, sizeof(cover), 0); End; Procedure quicksort1; Procedure partition(l,h: longint); Var i,j,p,temp1: longint; temp2: rec; Begin If l >= h then exit; i:= l; j:= h; p:= x[random(h - l + 1) + l]; Repeat While x[i] < p do inc(i); While x[j] > p do dec(j); If i <= j then Begin If i < j then Begin temp1:= x[i]; x[i]:= x[j]; x[j]:= temp1; temp2:= lab[i]; lab[i]:= lab[j]; lab[j]:= temp2; End; inc(i); dec(j); End; Until i > j; partition(l,j); partition(i,h); End; Begin partition(1,2 * n); End; Procedure quicksort2; Procedure partition(l,h: longint); Var i,j,p,temp1: longint; Begin If l >= h then exit; i:= l; j:= h; p:= c[random(h - l + 1) + l]; Repeat While c[i] < p do inc(i); While c[j] > p do dec(j); If i <= j then Begin If i < j then Begin temp1:= c[i]; c[i]:= c[j]; c[j]:= temp1; End; inc(i); dec(j); End; Until i > j; partition(l,j); partition(i,h); End; Begin partition(1,2 * n); End; Procedure open_true(A, B, k, l, h: longint); Var mid: longint; Begin If (h <= c[A]) or (c[B] <= l) then exit; If (l <= c[A]) and (c[B] <= h) then Begin inc(number[k]); cover[k]:= c[B] - c[A]; exit; End; If A + 1 >= B then exit; mid:= (A + B) div 2; open_true(A, mid, 2 * k, l, h); open_true(mid, B, 2 * k + 1, l, h); If number[k] = 0 then cover[k]:= cover[2 * k] + cover[2 * k + 1]; End; Procedure open_false(A, B, k, l, h: longint); Var mid: longint; Begin If (h <= c[A]) or (c[B] <= l) then exit; If (l <= c[A]) and (c[B] <= h) then Begin dec(number[k]); If number[k] = 0 then cover[k]:= cover[2 * k] + cover[2 * k + 1]; exit; End; If A + 1 >= B then Begin cover[k]:= 0; exit; End; mid:= (A + B) div 2; open_false(A, mid, 2 * k, l, h); open_false(mid, B, 2 * k + 1, l, h); If number[k] = 0 then cover[k]:= cover[2 * k] + cover[2 * k + 1]; End; Procedure solve; Var f: text; i: longint; Begin Assign(f, output); Rewrite(f); quicksort1; quicksort2; open_true(1, 2 * n, 1, lab[1].low, lab[1].high); S:= 0; For i:= 2 to 2 * n do Begin S:= S + cover[1] * (x[i] - x[i - 1]); If lab[i].open then open_true(1, 2 * n, 1, lab[i].low, lab[i].high) else open_false(1, 2 * n, 1, lab[i].low, lab[i].high); End; Writeln(f, S); Close(f); End; Begin init; solve; End.
Code mẫu của skyvn97
#include<cassert> #include<cstdio> #include<vector> #define MAX 30030 #define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i=i+1) #define REP(i,n) for (int i=0,_n=(n);i<_n;i=i+1) using namespace std; class SegmentTree { private: vector<int> cnt,add; int n; void update(int i,int l,int r,int u,int v,int c) { if (l>v || r<u || l>r || v<u) return; assert(0<=i && i<cnt.size()); if (u<=l && r<=v) { add[i]+=c; return; } int m=(l+r)>>1; update(2*i,l,m,u,v,c); update(2*i+1,m+1,r,u,v,c); int L=add[2*i]>0?m-l+1:cnt[2*i]; int R=add[2*i+1]>0?r-m:cnt[2*i+1]; cnt[i]=L+R; } public: SegmentTree() { n=0; } SegmentTree(int n) { this->n=n; cnt.assign(4*n+7,0); add.assign(4*n+7,0); } void update(int l,int r,int v) { update(1,1,n,l,r,v); } int countCell(void) const { return (add[1]>0?n:cnt[1]); } }; struct Event { int l,r,v; Event() { l=r=v=0; } Event(int _l,int _r,int _v) { l=_l;r=_r;v=_v; } }; struct Rectangle { int x1,y1,x2,y2; Rectangle() { x1=y1=x2=y2=0; } void input(void) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); x1++;y1++; } bool valid(void) const { return (x1<=x2 && y1<=y2); } }; Rectangle rec[MAX+7]; vector<Event> event[MAX+7]; int n; void init(void) { scanf("%d",&n); FOR(i,1,n) rec[i].input(); } void process(void) { FOR(i,1,n) if (rec[i].valid()) { event[rec[i].x1].push_back(Event(rec[i].y1,rec[i].y2,1)); event[rec[i].x2+1].push_back(Event(rec[i].y1,rec[i].y2,-1)); } SegmentTree segTree(MAX); int res=0; FOR(i,1,MAX) { REP(j,event[i].size()) segTree.update(event[i][j].l,event[i][j].r,event[i][j].v); res+=segTree.countCell(); } printf("%d\n",res); } int main(void) { init(); process(); return 0; }
Code mẫu của khuc_tuan
#include <iostream> using namespace std; #define mn 20001 #define mt 131071 typedef struct{ int num,val; } data; typedef struct{ int x1,x2,y; bool io; } vertex; data d[mt]; vertex a[mn]; int n; inline void update(int k,int first,int last,int u,int v,bool is_open){ if (first>v||last<u) return ; int n1=k<<1,n2=1+(k<<1); if (first>=u&&last<=v){ if (is_open){ if (!(d[k].num++)) d[k].val=last-first; } else{ if (!(--d[k].num)) d[k].val=d[n1].val+d[n2].val; } return ; } int mid=(first+last)>>1; if (first<mid){ update(n1,first,mid,u,v,is_open); update(n2,mid,last,u,v,is_open); if (!(d[k].num)) d[k].val=d[n1].val+d[n2].val; } } inline bool cmp(vertex u,vertex v){ if (u.y<v.y) return(true); return(false); } inline void cal(){ int area=0; for(int i=1;i<(n<<1);i++){ update(1,0,30000,a[i].x1,a[i].x2,a[i].io); area+=(a[i+1].y-a[i].y)*d[1].val; } printf("%d",area); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d%d%d",&a[i].x1,&a[i].y,&a[i].x2,&a[i+n].y); a[i+n].x1=a[i].x1;a[i+n].x2=a[i].x2; a[i].io=true;a[i+n].io=false; } sort(a+1,a+1+(n<<1),cmp); cal(); }
Comments