Hướng dẫn giải của VM 09 Bài 07 - Bắn bi


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

const fi='';
      fo='';
      maxn=50010;
var n,q,k,i,x,y,v,t,u:longint; re,tt,uu,nn:qword;
    rmax,rmin,cmax,cmin,a,b,c,d:array[1..maxn*4] of longint;
    ch:char;

function max(t,u:longint):longint;
begin
     if t<u then max:=u else max:=t;
end;

function min(t,u:longint):longint;
begin
     if t<u then min:=t else min:=u;
end;

procedure updaterow(node,l,r,x,y,v:longint);
var mid:longint;
begin
     if (l=x) and (r=y) then
     begin
          a[node]:=min(a[node],v);
          b[node]:=max(b[node],v);
          rmin[node]:=min(rmin[node],a[node]);
          rmax[node]:=max(rmax[node],b[node]);
     end
     else
     begin
          mid:=(l+r) shr 1;
          if x<=mid then updaterow(node shl 1,l,mid,x,min(y,mid),v);
          if mid<y then updaterow(node shl 1+1,mid+1,r,max(x,mid+1),y,v);
          rmin[node]:=min(min(rmin[node shl 1],rmin[node shl 1+1]),a[node]);
          rmax[node]:=max(max(rmax[node shl 1],rmax[node shl 1+1]),b[node]);
     end;
end;

procedure updatecol(node,l,r,x,y,v:longint);
var mid:longint;
begin
     if (l=x) and (r=y) then
     begin
          c[node]:=min(c[node],v);
          d[node]:=max(d[node],v);
          cmin[node]:=min(cmin[node],c[node]);
          cmax[node]:=max(cmax[node],d[node]);
     end
     else
     begin
          mid:=(l+r) shr 1;
          if x<=mid then updatecol(node shl 1,l,mid,x,min(y,mid),v);
          if mid<y then updatecol(node shl 1+1,mid+1,r,max(x,mid+1),y,v);
          cmin[node]:=min(min(cmin[node shl 1],cmin[node shl 1+1]),c[node]);
          cmax[node]:=max(max(cmax[node shl 1],cmax[node shl 1+1]),d[node]);
     end;
end;

procedure calcrmin(node,l,r,x:longint;var t:longint);
var mid,u:longint;
begin
     if (l=x) and (r=x) then
     begin
          t:=rmin[node];
          exit;
     end;
     mid:=(l+r) shr 1; u:=n+1;
     if x<=mid then
     begin
          calcrmin(node shl 1,l,mid,x,u);
          t:=min(a[node],u);
     end
     else
     begin
          calcrmin(node shl 1+1,mid+1,r,x,u);
          t:=min(a[node],u);
     end;
end;

procedure calcrmax(node,l,r,x:longint;var t:longint);
var mid,u:longint;
begin
     if (l=x) and (r=x) then
     begin
          t:=rmax[node];
          exit;
     end;
     mid:=(l+r) shr 1; u:=0;
     if x<=mid then
     begin
          calcrmax(node shl 1,l,mid,x,u);
          t:=max(b[node],u);
     end
     else
     begin
          calcrmax(node shl 1+1,mid+1,r,x,u);
          t:=max(b[node],u);
     end;
end;

procedure calccmin(node,l,r,x:longint;var t:longint);
var mid,u:longint;
begin
     if (l=x) and (r=x) then
     begin
          t:=cmin[node];
          exit;
     end;
     mid:=(l+r) shr 1; u:=n+1;
     if x<=mid then
     begin
          calccmin(node shl 1,l,mid,x,u);
          t:=min(c[node],u);
     end
     else
     begin
          calccmin(node shl 1+1,mid+1,r,x,u);
          t:=min(c[node],u);
     end;
end;

procedure calccmax(node,l,r,x:longint;var t:longint);
var mid,u:longint;
begin
     if (l=x) and (r=x) then
     begin
          t:=cmax[node];
          exit;
     end;
     mid:=(l+r) shr 1; u:=0;
     if x<=mid then
     begin
          calccmax(node shl 1,l,mid,x,u);
          t:=max(d[node],u);
     end
     else
     begin
          calccmax(node shl 1+1,mid+1,r,x,u);
          t:=max(d[node],u);
     end;
end;

begin
     assign(input,fi); reset(input);
     assign(output,fo); rewrite(output);
     readln(n,k,q); nn:=n;
     for i:=1 to n*4 do
     begin
          cmin[i]:=n+1; rmin[i]:=n+1;
          a[i]:=n+1; c[i]:=n+1;
     end;
     for i:=1 to k do
     begin
          readln(x,y);
          updaterow(1,1,n,x,x,y);
          updatecol(1,1,n,y,y,x);
     end;
     for i:=1 to q do
     begin
          readln(ch,v,x,y);
          case ch of
          'T':begin
                   calccmin(1,1,n,y,t);
                   if t=1 then
                   begin
                        writeln(0); continue;
                   end;
                   if t=n+1 then re:=nn*v
                   else
                   begin
                        u:=max(1,t-v);
                        dec(t);
                        tt:=t; uu:=u;
                        re:=(tt+uu)*(tt-uu+1) shr 1;
                        updatecol(1,1,n,y,y,u);
                        updaterow(1,1,n,u,t,y);
                   end;
              end;
          'B':begin
                   calccmax(1,1,n,y,t);
                   if t=n then
                   begin
                        writeln(0); continue;
                   end;
                   if t=0 then re:=nn*v
                   else
                   begin
                        u:=min(n,t+v);
                        inc(t);
                        tt:=t; uu:=u;
                        re:=(nn*2-tt-uu+2)*(uu-tt+1) shr 1;
                        updatecol(1,1,n,y,y,u);
                        updaterow(1,1,n,t,u,y);
                   end;
              end;
          'L':begin
                   calcrmin(1,1,n,x,t);
                   if t=1 then
                   begin
                        writeln(0); continue;
                   end;
                   if t=n+1 then re:=nn*v
                   else
                   begin
                        u:=max(1,t-v);
                        dec(t);
                        tt:=t; uu:=u;
                        re:=(tt+uu)*(tt-uu+1) shr 1;
                        updaterow(1,1,n,x,x,u);
                        updatecol(1,1,n,u,t,x);
                   end;
              end;
          'R':begin
                   calcrmax(1,1,n,x,t);
                   if t=n then
                   begin
                        writeln(0); continue;
                   end;
                   if t=0 then re:=nn*v
                   else
                   begin
                        u:=min(n,t+v);
                        inc(t);
                        tt:=t; uu:=u;
                        re:=(2*nn-tt-uu+2)*(uu-tt+1) shr 1;
                        updaterow(1,1,n,x,x,u);
                        updatecol(1,1,n,t,u,x);
                   end;
              end;
          end;
          writeln(re);
     end;
     close(input); close(output);
end.

Code mẫu của ladpro98

#include <bits/stdc++.h>

using namespace std;

const int INF = 1e9;

struct Node {
    int _min, _max;
    int l, r;
    Node *left, *right;
    Node(int l, int r):
        l(l), r(r), _min(INF), _max(-INF), left(NULL), right(NULL) {}

    int getMin(int i) {
        if (l == r) return _min;
        if (i <= (l + r >> 1))
            return min(_min, left->getMin(i));
        return min(_min, right->getMin(i));
    }

    int getMax(int i) {
        if (l == r) return _max;
        if (i <= (l + r >> 1))
            return max(_max, left->getMax(i));
        return max(_max, right->getMax(i));
    }

    void update(int i, int j, int v) {
        if (r < i || j < l) return;
        if (i <= l && r <= j) {
            _min = min(_min, v);
            _max = max(_max, v);
            return;
        }
        left->update(i, j, v);
        right->update(i, j, v);
    }
};

Node *build(int l, int r) {
    Node *x = new Node(l, r);
    if (l == r) return x;
    x->left = build(l, l + r >> 1);
    x->right = build((l + r >> 1) + 1, r);
    return x;
}

long long calc(long long n, int &c) {
    if (c > n) c = n;
    return (n * (n + 1) - (n - c) * (n - c + 1)) / 2;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(NULL);
    int n, k, q; cin >> n >> k >> q;
    Node *row = build(1, n);
    Node *col = build(1, n);
    for (int i = 1; i <= k; ++i) {
        int x, y;
        cin >> x >> y;
        row->update(y, y, x);
        col->update(x, x, y);
    }
    while (q--) {
        char cmd; int x, y, c;
        cin >> cmd >> c >> x >> y;
        long long ans = 1LL * c * n;
        if (cmd == 'L') {
            int to = col->getMin(x);
            if (to != INF) {
                ans = calc(to - 1, c);
                row->update(to - c, to - 1, x);
                col->update(x, x, to - c);
            }
        } else if (cmd == 'R') {
            int to = col->getMax(x);
            if (to != -INF) {
                ans = calc(n - to, c);
                row->update(to + 1, to + c, x);
                col->update(x, x, to + c);
            }
        } else if (cmd == 'T') {
            int to = row->getMin(y);
            if (to != INF) {
                ans = calc(to - 1, c);
                col->update(to - c, to - 1, y);
                row->update(y, y, to - c);
            }
        } else {
            int to = row->getMax(y);
            if (to != -INF) {
                ans = calc(n - to, c);
                col->update(to + 1, to + c, y);
                row->update(y, y, to + c);
            }
        }
        cout << ans << '\n';
    }
    return 0;
}

Code mẫu của RR

//Written by RR
{$ifdef rr}
  {$mode objfpc}
  {$inline off}
  {$r+,q+}
{$else}
  {$mode objfpc}
  {$inline on}
  {$r-,q-}
{$endif}

uses math;
const
  FINP          =       '';
  FOUT          =       '';
  MAXN          =       50111;
  snode         =       262144;
  sign          :       array[0..3] of longint=(1,-1,1,-1);

var
  f1,f2         :       text;
  n,q,k,oo      :       longint;
  it            :       array[0..3,1..snode] of longint;

procedure openF;
    begin
      assign(f1,FINP); reset(f1);
      assign(f2,FOUT); rewrite(f2);
    end;
procedure closeF;
    begin
      close(f1);
      close(f2);
    end;

procedure paint(x,i:longint); inline;
    begin
      it[x,i<<1]  :=min(it[x,i<<1]  ,it[x,i]);
      it[x,i<<1+1]:=min(it[x,i<<1+1],it[x,i]);
      it[x,i]:=oo;
    end;

procedure update(x,u,v,k:longint);
        procedure visit(i,l,r:longint); inline;
        var
          mid:longint;
        begin
          if l>r then exit;
          if (l<>r) and (it[x,i]<>oo) then paint(x,i);
          if (v<l) or (r<u) then exit;
          if (u<=l) and (r<=v) then
            begin
              it[x,i]:=min(it[x,i],k);
              exit;
            end;
          mid:=(l+r)>>1;
          visit(i<<1,l,mid);
          visit(i<<1+1,mid+1,r);
        end;
    begin
      k:=k*sign[x];
      visit(1,1,n);
    end;

function get(x,u:longint):longint;
    var
      kq:longint;
        procedure visit(i,l,r:longint);
        var
          mid:longint;
        begin
          if l>r then exit;
          if (u<l) or (r<u) then exit;
          if (l=r) and (r=u) then
            begin
              kq:=min(kq,it[x,i]);
              exit;
            end;
          mid:=(l+r)>>1;
          if (l<>r) and (it[x,i]<>oo) then paint(x,i);
          visit(i<<1,l,mid);
          visit(i<<1+1,mid+1,r);
        end;
    begin
      kq:=oo;
      visit(1,1,n);
      exit(kq*sign[x]);
    end;

procedure inp;
    var
      i,u,v:longint;
    begin
      read(f1,n,k,q);
      oo:=n+5;
      for u:=0 to 3 do
      for i:=1 to snode do
          it[u,i]:=oo;

      update(0,1,n,n+1);
      update(1,1,n,0);
      update(2,1,n,n+1);
      update(3,1,n,0);

      for i:=1 to k do
        begin
          readln(f1,u,v);
          update(0,u,u,v);
          update(1,u,u,v);
          update(2,v,v,u);
          update(3,v,v,u);
        end;
    end;

procedure solve;
    var
      i:longint;
      c:char;
      u,v,last:longint;
      d:int64;
    begin
      for i:=1 to q do
        begin
          if i=6 then
            write;
          readln(f1,c,d,u,v);
          if d=0 then begin writeln(f2,0); continue; end;
          case c of
            'L': begin
                   last:=get(0,u);
                   if (last=n+1) then
                     begin
                       writeln(f2,n*d);
                       continue;
                     end;
                   if last-d<=0 then d:=last-1;
                   writeln(f2,(last-1+last-d)*d>>1);
                   update(0,u,u,last-d);
                   update(1,u,u,last-1);
                   update(2,last-d,last-1,u);
                   update(3,last-d,last-1,u);
                 end;
            'R': begin
                   last:=get(1,u);
                   if (last=0) then
                     begin
                       writeln(f2,n*d);
                       continue;
                     end;
                   if last+d>n then d:=n-last;
                   writeln(f2,(n-last+n-last-d+1)*d>>1);
                   update(0,u,u,last+1);
                   update(1,u,u,last+d);
                   update(2,last+1,last+d,u);
                   update(3,last+1,last+d,u);
                 end;
            'T': begin
                   last:=get(2,v);
                   if (last=n+1) then
                     begin
                       writeln(f2,n*d);
                       continue;
                     end;
                   if last-d<=0 then d:=last-1;
                   writeln(f2,(last-1+last-d)*d>>1);
                   update(1,last-d,last-1,v);
                   update(0,last-d,last-1,v);
                   update(2,v,v,last-d);
                   update(3,v,v,last-1);
                 end;
            'B': begin
                   last:=get(3,v);
                   if (last=0) then
                     begin
                       writeln(f2,n*d);
                       continue;
                     end;
                   if last+d>n then d:=n-last;
                   writeln(f2,(n-last+n-last-d+1)*d>>1);
                   update(1,last+1,last+d,v);
                   update(0,last+1,last+d,v);
                   update(2,v,v,last+1);
                   update(3,v,v,last+d);
                 end;
          end;
        end;
    end;

begin
  openF;
  inp;
  solve;
  closeF;
end.

Code mẫu của hieult

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cassert>
#include<ctime>
#include<algorithm>
#include<iterator>
#include<iostream>
#include<cctype>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<list>
//#include<conio.h>
#define ep 0.000001
#define maxn 50005
#define mod 1000000000
#define oo 1000000005
#define TR(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++)
#define fi first 
#define se second

double const PI=4*atan(1);
//double const oo = 1e19;

using namespace std;

typedef pair<int, int> II;
typedef vector<int> VI;
typedef vector<II> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;

struct tree{
    int small, big;
    tree(){};
    tree(int _small, int _big){ small = _small, big = _big;}
};

tree init = tree(oo, -oo);
tree f[2][maxn * 4];
int a[2][maxn];
int n, k, q, r, c, u, v, KQ, num;
char s[2];

void update(int l, int r,int i,int h,int gt){
    if(u > r || v < l) return;
    else if(u <= l && v >= r){
        f[h][i].small = min(f[h][i].small, gt);
        f[h][i].big = max(f[h][i].big, gt);
        return;
    }
    int mid = (l + r) / 2;
    update(l, mid, i + i, h, gt);
    update(mid + 1, r, i + i + 1, h, gt);
} 

void get(int l, int r, int i,int h, int can){
    if(u < l || u > r) return ;
    if(can == -1) KQ = min(KQ, f[h][i].small);
    else KQ = max(KQ, f[h][i].big);
    if(l == r) return;
    int mid = (l + r) / 2;
    get(l, mid, i + i, h, can);
    get(mid + 1, r, i + i + 1, h, can);
}

int main(){
   // freopen("input.in","r",stdin); 
   // freopen("output.out","w",stdout);
    scanf("%d %d %d", &n, &k, &q);
    for(int i = 1; i <= 4 * n + 1; i++) for(int j = 0; j < 2; j++) f[j][i] = init;
    for(int i = 0; i < k; i++){
        scanf("%d %d", &r, &c);
        u = c, v = c;
        update(1, n, 1, 0, r);
        u = r, v = r;
        update(1, n, 1, 1, c);
    }
    for(int i = 0; i < q; i++){
        scanf("%s %d %d %d", s, &num, &r, &c);
        if(s[0] == 'L'){
            KQ = oo; u = r;
            get(1, n, 1, 1, -1);
            if(KQ >= oo) printf("%lld\n",(long long)num * n);
            else{
                int t = max(1, KQ - num);
                printf("%lld\n",((long long)KQ * (KQ - 1) - (long long)t * (t - 1)) / 2);
              //  printf("%d %d\n",t,KQ);
                u = t, v = KQ;
                update(1, n, 1, 0, r);
                u = r; v = r;
                update(1, n, 1, 1, t);
            }
        }

        else if(s[0] == 'R'){
            KQ = -oo; u = r;
            get(1, n, 1, 1, 1);
            if(KQ <= -oo) printf("%lld\n",(long long)num * n);
            else{
                int t = min(n, KQ + num);
                printf("%lld\n",((long long)(n - KQ) * (n - KQ + 1) - (long long)(n - t) * (n - t + 1))/2);
                u = KQ, v = t;
                update(1, n, 1, 0, r);
                u = r, v = r;
                update(1, n, 1, 1, t);
            }
        }
        else if(s[0] == 'T'){
            KQ = oo; u = c;
            get(1, n, 1, 0, -1);
            if(KQ >= oo) printf("%lld\n",(long long)num * n);
            else{
                int t = max(1, KQ - num);
                printf("%lld\n",((long long)KQ * (KQ - 1) - (long long)t * (t - 1)) / 2);
                u = t, v = KQ;
                update(1, n, 1, 1, c);
                u = c; v = c;
                update(1, n, 1, 0, t);
            }
        }
        else {
            KQ = -oo; u = c;
            get(1, n, 1, 0, 1);
            if(KQ <= -oo) printf("%lld\n",(long long)num * n);
            else{
                int t = min(n, KQ + num);
                printf("%lld\n",((long long)(n - KQ) * (n - KQ + 1) - (long long)(n - t) * (n - t + 1))/2);
                u = KQ, v = t;
                update(1, n, 1, 1, c);
                u = c, v = c;
                update(1, n, 1, 0, t);
            }
        }
    }
}

Code mẫu của ll931110

{$MODE DELPHI}
{$inline on}
program MARBLE;
uses math;
const
  input  = '';
  output = '';
  maxn = 50000;
  maxv = 8 * maxn;
type
  rec = record
    min,max: integer;
    flagmin,flagmax: boolean;
  end;
  rec2 = record
    min,max: integer;
  end;
var
  r,c: array[1..maxv] of rec;
  n,q,k: integer;
  val,pos: integer;
  u,v: int64;
  ch: char;
  fi,fo: text;
  t,cs: rec2;

procedure openfile;inline;
begin
  assign(fi, input);
    reset(fi);

  assign(fo, output);
    rewrite(fo);
end;



{Interval tree's operators}
{-------------------------------------------------------------}

procedure flag_row(i: integer);inline;
begin
  if r[i].flagmin then
    begin
      r[i].flagmin := false;

      if r[2 * i].min > r[i].min then
        begin
          r[2 * i].min := r[i].min;
          r[2 * i].flagmin := true;
        end;

      if r[2 * i + 1].min > r[i].min then
        begin
          r[2 * i + 1].min := r[i].min;
          r[2 * i + 1].flagmin := true;
        end;
    end;

  if r[i].flagmax then
    begin
      r[i].flagmax := false;

      if r[2 * i].max < r[i].max then
        begin
          r[2 * i].max := r[i].max;
          r[2 * i].flagmax := true;
        end;

      if r[2 * i + 1].max < r[i].max then
        begin
          r[2 * i + 1].max := r[i].max;
          r[2 * i + 1].flagmax := true;
        end;
    end;
end;

procedure update_row(i,low,high: integer);inline;
var
  mid: integer;
begin
  if (v < low) or (high < u) then exit;
  if (u <= low) and (high <= v) then
    begin
      if r[i].min >= val then
        begin
          r[i].min := val;
          r[i].flagmin := true;
        end;
      if r[i].max <= val then
        begin
          r[i].max := val;
          r[i].flagmax := true;
        end;
      exit;
    end;

  flag_row(i);
  mid := (low + high) div 2;
  update_row(2 * i,low,mid);
  update_row(2 * i + 1,mid + 1,high);

  r[i].min := max(r[2 * i].min,r[2 * i + 1].min);
  r[i].max := min(r[2 * i].max,r[2 * i + 1].max);
end;

procedure calc_row(i,low,high: integer);inline;
var
  mid: integer;
begin
  if low = high then
    begin
      if low = val then
        begin
          t.min := r[i].min;
          t.max := r[i].max;
        end;
      exit;
    end;

  flag_row(i);
  mid := (low + high) div 2;
  if val <= mid then calc_row(2 * i,low,mid)
                else calc_row(2 * i + 1,mid + 1,high);

  r[i].min := max(r[2 * i].min,r[2 * i + 1].min);
  r[i].max := min(r[2 * i].max,r[2 * i + 1].max);
end;

procedure flag_col(i: integer);inline;
begin
  if c[i].flagmin then
    begin
      c[i].flagmin := false;

      if c[2 * i].min > c[i].min then
        begin
          c[2 * i].min := c[i].min;
          c[2 * i].flagmin := true;
        end;

      if c[2 * i + 1].min > c[i].min then
        begin
          c[2 * i + 1].min := c[i].min;
          c[2 * i + 1].flagmin := true;
        end;
    end;

  if c[i].flagmax then
    begin
      c[i].flagmax := false;

      if c[2 * i].max < c[i].max then
        begin
          c[2 * i].max := c[i].max;
          c[2 * i].flagmax := true;
        end;

      if c[2 * i + 1].max < c[i].max then
        begin
          c[2 * i + 1].max := c[i].max;
          c[2 * i + 1].flagmax := true;
        end;
    end;
end;

procedure update_col(i,low,high: integer);inline;
var
  mid: integer;
begin
  if (v < low) or (high < u) then exit;
  if (u <= low) and (high <= v) then
    begin
      if c[i].min >= val then
        begin
          c[i].min := val;
          c[i].flagmin := true;
        end;
      if c[i].max <= val then
        begin
          c[i].max := val;
          c[i].flagmax := true;
        end;
      exit;
    end;

  flag_col(i);
  mid := (low + high) div 2;
  update_col(2 * i,low,mid);
  update_col(2 * i + 1,mid + 1,high);

  c[i].min := max(c[2 * i].min,c[2 * i + 1].min);
  c[i].max := min(c[2 * i].max,c[2 * i + 1].max);
end;

procedure calc_col(i,low,high: integer);inline;
var
  mid: integer;
begin
  if low = high then
    begin
      if low = val then
        begin
          t.min := c[i].min;
          t.max := c[i].max;
        end;
      exit;
    end;

  flag_col(i);
  mid := (low + high) div 2;
  if val <= mid then calc_col(2 * i,low,mid)
                else calc_col(2 * i + 1,mid + 1,high);

  c[i].min := max(c[2 * i].min,c[2 * i + 1].min);
  c[i].max := min(c[2 * i].max,c[2 * i + 1].max);
end;



{-----------------------------------------------------------------}
{End of Interval tree's operators}



procedure init;inline;
var
  i: integer;
begin
  cs.min := maxv;
  cs.max := -maxv;

  readln(fi, n, k, q);
  for i := 1 to 8 * maxn do
    begin
      r[i].min := maxv;
      r[i].max := -maxv;
      r[i].flagmin := false;
      r[i].flagmax := false;

      c[i].min := maxv;
      c[i].max := -maxv;
      c[i].flagmax := false;
      c[i].flagmax := false;
    end;
end;

procedure solve;inline;
var
  i,x,y: integer;
  res,d: int64;
begin
  for i := 1 to k do
    begin
      readln(fi, x, y);

      u := x;
      v := x;
      val := y;
      update_row(1,1,n);

      u := y;
      v := y;
      val := x;
      update_col(1,1,n);
    end;

  for i := 1 to q do
    begin
      t := cs;
      readln(fi, ch, d, x, y);

      if (ch = 'L') or (ch = 'R') then
        begin
          val := x;
          calc_row(1,1,n);

          if ch = 'L' then
            begin
              if t.min = maxv then res := int64(d * n)
              else
                begin
                  v := t.min - 1;
                  u := v - d + 1;
                  if u <= 0 then u := 1;

                  res := int64((v - u + 1) * (u + v)) div 2;
                  update_col(1,1,n);

                  val := u;
                  u := x;
                  v := x;
                  update_row(1,1,n);
                end;
            end
          else
            begin
              if t.max = -maxv then res := int64(d * n)
              else
                begin
                  u := t.max + 1;
                  v := u + d - 1;
                  if v > n then v := n;

                  res := int64((v - u + 1) * (2 * (n + 1) - u - v)) div 2;
                  update_col(1,1,n);

                  val := v;
                  u := x;
                  v := x;
                  update_row(1,1,n);
                end;
            end;
        end
      else if (ch = 'T') or (ch = 'B') then
        begin
          val := y;
          calc_col(1,1,n);

          if ch = 'T' then
            begin
              if t.min = maxv then res := int64(d * n)
              else
                begin
                  v := t.min - 1;
                  u := v - d + 1;
                  if u <= 0 then u := 1;

                  res := int64((v - u + 1) * (u + v)) div 2;
                  update_row(1,1,n);

                  val := u;
                  u := y;
                  v := y;
                  update_col(1,1,n);
                end;
            end
          else
            begin
              if t.max = -maxv then res := int64(d * n)
              else
                begin
                  u := t.max + 1;
                  v := u + d - 1;
                  if v > n then v := n;

                  res := int64((v - u + 1) * (2 * (n + 1) - u - v)) div 2;
                  update_row(1,1,n);

                  val := v;
                  u := y;
                  v := y;
                  update_col(1,1,n);
                end;
            end;
          end;

      writeln(fo, res);
    end;
end;

procedure closefile;inline;
begin
  close(fo);
  close(fi);
end;

begin
  openfile;
  init;
  solve;
  closefile;
end.

Code mẫu của khuc_tuan

#include <cstdio>
#include <algorithm>
using namespace std;

const int MAXN = 50050;

struct Data {
    int min, max, color;
};

int n, K, Q;
Data L[MAXN * 4], R[MAXN * 4], T[MAXN * 4], B[MAXN * 4];
char buf[1000];

int F1(Data d, int x) {
    int r = 0;
    if(x <= d.min) r = 1;
    if(x >= d.max) r = -1;
    return r;
}

int F2(Data d, int x) {
    return -F1(d, x);
}

void fill(int n, int l, int r, int x, int y, int c, int c2, Data T[], int (*F)(Data d, int x)) {
    if(x > y) return;
    if(T[n].color != -1 && c2 == -1) c2 = T[n].color;
    int decision = F(T[n], c);
    if(decision == 1) return;
    if(decision == -1 && x <= l && r <= y) {
        T[n].color = T[n].min = T[n].max = c;
        return;
    }
    T[n].color = -1;
    int m = (l + r) / 2;
    if(x <= m) fill( 2 * n, l, m, x, y, c, c2, T, F);
    else if(c2 != -1) T[2 * n].color = T[2 * n].min = T[2 * n].max = c2;

    if(m < y) fill( 2 * n + 1, m + 1, r, x, y, c, c2, T, F);
    else if(c2 != -1) T[2* n + 1].color = T[2 * n + 1].min = T[2 * n + 1].max = c2;

    T[n].min = min(T[2 * n].min, T[2 * n + 1].min);
    T[n].max = max(T[2 * n].max, T[2 * n + 1].max);
}

int getcolor(int n, int l, int r, int pos, Data T[]) {
    if(T[n].color != -1) return T[n].color;
    else {
        int m = (l + r) / 2;
        if(pos <= m) return getcolor( 2 * n, l, m, pos, T);
        else return getcolor( 2 * n + 1, m + 1, r, pos, T);
    }
}

int main() {
    scanf("%d%d%d", &n, &K, &Q);
    for(int i=1;i<=n*4;++i) {
        T[i].min = T[i].max = T[i].color = L[i].min = L[i].max = L[i].color = 0;
        R[i].min = R[i].max = R[i].color = B[i].min = B[i].max = B[i].color = n + 1;
    }

    for(int i=0;i<K;++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        fill( 1, 1, n, u, u, v, -1, L, F1);
        fill( 1, 1, n, u, u, v, -1, R, F2);
        fill( 1, 1, n, v, v, u, -1, T, F1);
        fill( 1, 1, n, v, v, u, -1, B, F2);
    }

    gets(buf);  
    for(int i=0;i<Q;++i) {
        long long res = 0;
        int u, v, d, id, rem;
        char c;
        gets(buf);
        sscanf( buf, "%c%d%d%d", &c, &d, &u, &v);
        if(c == 'T') {
            id = getcolor( 1, 1, n, v, B);
            if(id > n) res += (long long) n * d;
            else {
                rem = min( id - 1, d);
                res += (long long) rem * (2 * id - 1 - rem) / 2;
                fill( 1, 1, n, id - rem, id - 1, v, -1, L, F1);
                fill( 1, 1, n, id - rem, id - 1, v, -1, R, F2);
                fill( 1, 1, n, v, v, id - rem, -1, B, F2);
            }
        }       
        if(c == 'B') {
            id = getcolor( 1, 1, n, v, T);
            if(id < 1) res += (long long) n * d;
            else {
                rem = min( n - id, d);
                res += (long long) rem * (2 * (n - id) - rem + 1) / 2;
                fill( 1, 1, n, id + 1, id + rem, v, -1, L, F1);
                fill( 1, 1, n, id + 1, id + rem, v, -1, R, F2);
                fill( 1, 1, n, v, v, id + rem, -1, T, F1);
            }   
        }
        if(c == 'L') {
            id = getcolor( 1, 1, n, u, R);
            if(id > n) res += (long long) n * d;
            else {
                rem = min( id - 1, d);
                res += (long long) rem * (2 * id - 1 - rem) / 2;
                fill( 1, 1, n, id - rem, id - 1, u, -1, T, F1);
                fill( 1, 1, n, id - rem, id - 1, u, -1, B, F2);
                fill( 1, 1, n, u, u, id - rem, -1, R, F2);
            }   
        }
        if(c == 'R') {
            id = getcolor( 1, 1, n, u, L);
            if(id < 1) res += (long long) n * d;
            else {
                rem = min( n - id, d);
                res += (long long) rem * (2 * (n - id) - rem + 1) / 2;
                fill( 1, 1, n, id + 1, id + rem, u, -1, T, F1);
                fill( 1, 1, n, id + 1, id + rem, u, -1, B, F2);
                fill( 1, 1, n, u, u, id + rem, -1, L, F1);
            }   
        }
        printf("%lld\n", res);
    }
    return 0;
}

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.