Editorial for Japan


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

const  maxn=1001;
var test,it,m,n,k:longint;
    f:array[1..maxn] of longint;
    a,b:array[1..maxn*maxn] of longint;
    re:int64;

procedure sort(l,r:longint);
var i,j,x,y,t:longint;
begin
     i:=l; j:=r; x:=a[(i+j) shr 1]; y:=b[(i+j) shr 1];
     repeat
           while (a[i]>x) or ((a[i]=x) and (b[i]>y)) do i:=i+1;
           while (a[j]<x) or ((a[j]=x) and (b[j]<y)) do j:=j-1;
           if i<=j then
           begin
                t:=a[i]; a[i]:=a[j]; a[j]:=t;
                t:=b[i]; b[i]:=b[j]; b[j]:=t;
                i:=i+1; j:=j-1;
           end;
     until i>j;
     if i<r then sort(i,r);
     if l<j then sort(l,j);
end;

function calc(x:longint):int64;
var r:int64;
begin
     r:=0;
     while x>0 do
     begin
          r:=r+f[x];
          x:=x-x and (-x);
     end;
     calc:=r;
end;

procedure add(x:longint);
begin
     while x<=n do
     begin
          f[x]:=f[x]+1;
          x:=x+x and (-x);
     end;
end;

procedure pr;
var i,x,y:longint;
begin
     read(m,n,k);
     re:=0;
     for i:=1 to k do read(a[i],b[i]);
     sort(1,k);
     fillchar(f,sizeof(f),0);
     for i:=1 to k do
     begin
          re:=re+calc(b[i]-1);
          add(b[i]);
     end;
     writeln('Test case ',it,': ',re);
end;

begin
     read(test);
     for it:=1 to test do pr;
end.

Code mẫu của happyboy99x

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

typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef long long LL;
#define fi first
#define se second
#define M 1000
#define TR(v, it) for(typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)

int bit[M+1], n, m, k;

bool cmp(const ii&a, const ii&b) {
    return a.fi < b.fi || a.fi == b.fi && a.se > b.se;
}

void add(int i, int v) {
    for(; i <= m; i += i & -i) bit[i] += v;
}

LL sum(int i) {
    LL res = 0;
    for(; i > 0; i -= i & -i) res += bit[i];
    return res;
}

int main() {
    int tc; scanf("%d", &tc);
    for(int test = 1; test <= tc; ++test) {
        vii hw; //highway
        scanf("%d%d%d", &n, &m, &k);
        for(int i = 0; i < k; ++i) {
            int x, y; scanf("%d%d", &x, &y);
            hw.push_back(ii(x, m-y+1));
        }
        sort(hw.begin(), hw.end(), cmp);
        memset(bit, 0, sizeof bit);
        LL res = 0;
        TR(hw, it) {
            res += sum(it->se - 1);
            add(it->se, 1);
        }
        printf("Test case %d: %lld\n", test, res);
    }
    return 0;
}

Code mẫu của ladpro98

program mse06h;
uses    math;
type    e=record
        x,y:longint;
        end;
const   fi='';
        maxT=1101;
        maxN=1101;
var     bit:array[1..maxT,1..maxn] of longint;
        a:array[1..maxn*maxn] of e;
        m,n,k,t,tt,time,i,j,p:longint;
        res:int64;
        inp:text;

procedure update(i:longint);
begin
        while i<=m do
        begin
                inc(bit[tt,i]);
                inc(i,i and (-i));
        end;
end;

function get(i:longint):longint;
var     sum:longint;
begin
        sum:=0;
        while i>0 do
        begin
                inc(sum,bit[tt,i]);
                dec(i,i and (-i));
        end;
        exit(sum);
end;

procedure swap(i,j:longint);
var     t:e;
begin
        t:=a[i];
        a[i]:=a[j];
        a[j]:=t;
end;

procedure sort(l,r:longint);
var     i,j:longint;
        p:e;
begin
        if l>=r then exit;
        i:=l;j:=r;
        p:=a[random(r-l+1)+l];
        repeat
                while (a[i].x<p.x) or ((a[i].x=p.x) and (a[i].y<p.y)) do inc(i);
                while (a[j].x>p.x) or ((a[j].x=p.x) and (a[j].y>p.y)) do dec(j);
                if i<=j then
                begin
                        if i<j then swap(i,j);
                        inc(i);dec(j);
                end;
        until i>j;
        sort(l,j);sort(i,r);
end;

begin
        assign(inp,fi);reset(inp);
        readln(inp,t);
        for tt:=1 to t do
        begin
                res:=0;
                readln(inp,n,m,k);
                for i:=1 to k do readln(inp,a[i].x,a[i].y);
                sort(1,k);
                i:=1;
                while i<=k do
                begin
                        j:=i;
                        while a[j].x=a[i].x do inc(j);
                        for p:=i to j-1 do
                                inc(res,get(m)-get(a[p].y));
                        for p:=i to j-1 do
                                update(a[p].y);
                        i:=j;
                end;
                writeln('Test case ',tt,': ',res);
        end;
end.

Code mẫu của RR

//Written by RR
{$IFDEF RR}
  {$R+,Q+}
  {$Mode objFPC}
  {$inline off}
{$ELSE}
  {$R-,Q-}
  {$Mode objFPC}
  {$inline on}
{$ENDIF}

uses math;
const
  FINP          =       {$IFDEF RR} 'input.txt';  {$ELSE} ''; {$ENDIF}
  FOUT          =       {$IFDEF RR} 'output.txt'; {$ELSE} ''; {$ENDIF}
  MAXN          =       1000111;

type
  BITree        =       object
        val     :       array[1..MAXN] of longint;
        procedure init;
        procedure update(u:longint);
        function get(u:longint):longint;
  end;

var
  f1,f2         :       text;
  n,m,k,test    :       longint;
  a,b           :       array[1..MAXN] of longint;
  bit           :       BITree;

procedure openF;
    begin
      assign(f1,FINP); reset(f1);
      assign(f2,FOUT); rewrite(f2);
    end;
procedure closeF;
    begin
      close(f1);
      close(f2);
    end;
procedure inp;
    var
      i:longint;
    begin
      read(f1,n,m,k);
      for i:=1 to k do
        read(f1,a[i],b[i]);
    end;
procedure swap(var a,b:longint); inline;
    var
      temp:longint;
    begin
      temp:=a; a:=b; b:=temp;
    end;
procedure BITree.init; inline;
    var
      i:longint;
    begin
      for i:=m downto 1 do
        val[i]:=0;
    end;
procedure BITree.update(u:longint); inline;
    var
      v:longint;
    begin
      inc(val[u]);
      v:=u+u and (-u);
      if v<=m then update(v);
    end;
function BITree.get(u:longint):longint; inline;
    var
      v,kq:longint;
    begin
      if u=0 then exit(0);
      kq:=val[u];
      v:=u-u and (-u);
      if v>0 then inc(kq,get(v));
      exit(kq);
    end;
procedure sort(l,r:longint); inline;
    var
      i,j,ma,mb,key:longint;
    begin
      i:=l; j:=r; key:=l+random(r-l+1);
      ma:=a[key]; mb:=b[key];
      repeat
        while (a[i]<ma) or ((a[i]=ma) and (b[i]<mb)) do inc(i);
        while (a[j]>ma) or ((a[j]=ma) and (b[j]>mb)) do dec(j);
        if i<=j then
          begin
            swap(a[i],a[j]);
            swap(b[i],b[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 solve;
    var
      i,u:longint;
      count:int64;
    begin
      count:=0;
      for i:=k downto 1 do
        begin
          u:=b[i];
          inc(count,bit.get(u-1) );
          bit.update(u);
        end;
      writeln(f2,'Test case ',test,': ',count);
    end;

begin
  openF;
  read(f1,test);
  for test:=1 to test do
    begin
      inp;
      bit.init;
      sort(1,k);
      solve;
    end;
  closeF;
end.

Code mẫu của hieult

#include <stdio.h>
//#include <conio.h>

int main()
{
   // freopen("MSE06H.inp","r",stdin);
    int test,n,m,k,a[1001][1001],f[1001][1001],x[1000001],y[1000001];
    scanf("%d",&test);
    for(int ii=1;ii<=test;ii++)
    {
        scanf("%d %d %d",&n,&m,&k);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                a[i][j]=0;
                f[i][j]=0;
            }
       // printf("%d %d %d\n",n,m,k);
        for(int i=1;i<=k;i++)
        {
            scanf("%d %d",&x[i],&y[i]);
            a[x[i]][y[i]]=1;
           //  printf("%d %d %d\n",i,x[i],y[i]);
        }
        for(int i=2;i<=n;i++)
        {
            int u = 0;
            for(int j=m;j>=1;j--)
            {
                f[i][j]=f[i-1][j]+u;
                if(a[i-1][j]==1)
                    u++;
            }
        }
        long long KQ = 0;
        for(int i=1;i<=k;i++)
        {
            KQ = KQ + f[x[i]][y[i]];
           // printf("%d %d\n",i,f[x[i]][y[i]]);
            }
        printf("Test case %d: %lld\n",ii,KQ);
    }
   // getch();
}

Code mẫu của ll931110

{$MODE DELPHI}
Program MSE06H;
Const
  input  = '';
  output = '';
  maxk = 1000000;
  maxn = 1000;
Type
  rec = record
    x,y: integer;
  end;
Var
  fi,fo: text;
  n,m,k,nTest,iTest: integer;
  a: array[1..maxn * maxn] of rec;
  b: array[1..maxn] of integer;
  tmp: array[1..maxn * maxn] of integer;

Procedure openfile;
Begin
  Assign(fi, input);
    Reset(fi);

  Assign(fo, output);
    Rewrite(fo);
End;

Procedure init;
Var
  i: integer;
Begin
  Readln(fi, n, m, k);
  For i:= 1 to k do readln(fi, a[i].x, a[i].y);
End;

Procedure swap(var t1,t2: rec);
Var
  t3: rec;
Begin
  t3:= t1;
  t1:= t2;
  t2:= t3;
End;

Function low(t1,t2: rec): boolean;
Begin
  low:= (t1.x < t2.x) or ((t1.x = t2.x) and (t1.y < t2.y));
End;

Procedure quicksort;

  Procedure partition(l,h: integer);
  Var
    i,j: integer;
    p: rec;
  Begin
    If l >= h then exit;
    i:= l;
    j:= h;
    p:= a[random(h - l + 1) + l];

    Repeat
      While low(a[i],p) do inc(i);
      While low(p,a[j]) do dec(j);

      If i <= j then
        Begin
          If i < j then swap(a[i],a[j]);
          inc(i);
          dec(j);
        End;
    Until i > j;

    partition(l,j);
    partition(i,h);
  End;

Begin
  partition(1,k);
End;

Procedure update(v: integer);
Begin
  While v >= 1 do
    Begin
      inc(b[v]);
      v:= v - (v and (-v));
    End;
End;

Function calc(v: integer): int64;
Var
  t: int64;
Begin
  t:= 0;
  While v <= maxn do
    Begin
      t:= t + b[v];
      v:= v + (v and (-v));
    End;
  calc:= t;
End;

Procedure solve;
Var
  res: int64;
  num,i,j: integer;
Begin
  Fillchar(b, sizeof(b), 0);
  res:= 0;
  num:= 1;
  tmp[1]:= a[1].y;

  For i:= 2 to k do
    Begin
      If a[i].x = a[i - 1].x then
        Begin
          inc(num);
          tmp[num]:= a[i].y;
        End
      else
        Begin
          For j:= 1 to num do update(tmp[j] - 1);
          num:= 1;
          tmp[1]:= a[i].y;
        End;

      res:= res + calc(a[i].y);
    End;

  Writeln(fo, 'Test case ', iTest, ': ', res);
End;

Procedure closefile;
Begin
  Close(fo);
  Close(fi);
End;

Begin
  openfile;

  Readln(fi, nTest);
  For iTest:= 1 to nTest do
    Begin
      init;
      quicksort;
      solve;
    End;

  closefile;
End.

Code mẫu của skyvn97

#include<cstdio>
#include<algorithm>
#define MAX   1010
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
ll t[MAX];
ii b[MAX*MAX];
int m,n,k;
int nt,c;
bool cmp(const ii &a,const ii &b) {
    if (a.first>b.first) return (true);
    if (a.first<b.first) return (false);
    return (a.second>b.second);
}
void init(void) {
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&k);
    int i;
    for (i=1;i<=k;i=i+1) {
        scanf("%d",&b[i].first);
        scanf("%d",&b[i].second);
    }
    for (i=1;i<=m;i=i+1) t[i]=0;
    sort(&b[1],&b[k+1],cmp);
}
void update(int i) {
    while (1<=i && i<=m) {
        t[i]++;
        i=i+(i&(-i));
    }
}
ll sum(int i) {
    ll res=0;
    while (1<=i && i<=m) {
        res=res+t[i];
        i=i&(i-1);
    }
    return (res);
}
void process(void) {
    int i;
    ll res=0;
    for (i=1;i<=k;i=i+1) {
        update(b[i].second);
        res=res+sum(b[i].second-1);
    }
    printf("Test case %d: %lld\n",c,res);
}
int main(void) {
    scanf("%d",&nt);
    for (c=1;c<=nt;c=c+1) {
        init();
        process();
    }
    return 0;
}

Comments

Please read the guidelines before commenting.


There are no comments at the moment.