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.

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

Please read the guidelines before commenting.


There are no comments at the moment.