Hướng dẫn giải của Diện tích 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.

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();
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.