Hướng dẫn giải của IOI01 Mobiles


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

var n,i,j,x,y,u,v,z:longint;
    a:array[1..1025,1..1025] of longint;

procedure add(x,y,z:longint);
var t:longint;
begin
     t:=y;
     while x<=n do
     begin
          y:=t;
          while y<=n do
          begin
               a[x,y]:=a[x,y]+z;
               y:=y+y and (-y);
          end;
          x:=x+x and (-x);
     end;
end;

function get(x,y:longint):longint;
var t,r:longint;
begin
     t:=y; r:=0;
     while x>0 do
     begin
          y:=t;
          while y>0 do
          begin
               r:=r+a[x,y];
               y:=y-y and (-y);
          end;
          x:=x-x and (-x);
     end;
     get:=r;
end;

begin
     read(n,n);
     while true do
     begin
          read(i);
          if i=3 then break;
          if i=1 then
          begin
               read(x,y,z);
               add(x+1,y+1,z);
          end
          else
          begin
               read(x,y,u,v);
               writeln(get(u+1,v+1)-get(x,v+1)-get(u+1,y)+get(x,y));
          end;
     end;
end.

Code mẫu của happyboy99x

#include<cstdio>

const int N = 1025;

int bit[N][N], s;

void update(int x, int y, int v) {
    for(int i=x; i<=s; i+=i&-i)
        for(int j=y; j<=s; j+=j&-j)
            bit[i][j] += v;
}

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

int main() {
    scanf("%*d%d",&s);
    int control;
    while(scanf("%d",&control) && control != 3) 
        if(control == 1) {
            int x, y, a; scanf("%d%d%d",&x,&y,&a);
            update(++x, ++y, a);
        } else {
            int l, b, r, t; scanf("%d%d%d%d",&l,&b,&r,&t);
            ++l; ++b; ++r; ++t;
            printf("%d\n",sum(r,t)-sum(r,b-1)-sum(l-1,t)+sum(l-1,b-1));
        }
    return 0;
}

Code mẫu của ladpro98

#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <climits>
#include <cstdlib>
#include <ctime>
#include <memory.h>
#include <cassert>

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define REP(i, a, b) for(int i = (a); i <=(b); i++)
#define FORD(i, a, b) for(int i = (a); i > (b); i--)
#define REPD(i, a, b) for(int i = (a); i >=(b); i--)
#define TR(it, a) for(typeof(a.begin()) it = a.begin(); it != a.end(); it++)
#define RESET(a, v) memset(a, (v), sizeof(a))
#define SZ(a) (int(a.size()))
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define LL long long
#define LD long double
#define II pair<int, int>
#define X first
#define Y second
#define VI vector<int>
#define VII vector<II>
#define endl '\n'

using namespace std;

int n;

struct nodeY {
    int l, r, sum;
    nodeY *left, *right;

    nodeY(int _l, int _r) {
        l = _l; r = _r; sum = 0;
        left = right = NULL;
    }

    void pushDown() {
        if (l != r && left == NULL) {
            left = new nodeY(l, l + r >> 1);
            right = new nodeY((l + r >> 1) + 1, r);
        }
    }

    void update(int i, int v) {
        if (r < i || i < l) return;
        pushDown();
        if (l == r) {
            sum += v;
            return;
        }
        left->update(i, v);
        right->update(i, v);
        sum = left->sum + right->sum;
    }

    int getSum(int i, int j) {
        if (r < i || j < l) return 0;
        pushDown();
        if (i <= l && r <= j) return sum;
        return left->getSum(i, j) + right->getSum(i, j);
    }
};

struct nodeX {
    int l, r, sum;
    nodeX *left, *right;
    nodeY *node;

    nodeX(int _l, int _r) {
        l = _l; r = _r; sum = 0;
        left = right = NULL;
        node = new nodeY(0, n - 1);
    }

    void pushDown() {
        if (l != r && left == NULL) {
            left = new nodeX(l, l + r >> 1);
            right = new nodeX((l + r >> 1) + 1, r);
        }
    }

    void update(int x, int y, int value) {
        if (r < x || x < l) return;
        pushDown();
        node->update(y, value);
        if (l == r) return;
        left->update(x, y, value);
        right->update(x, y, value);
    }

    int getSum(int x, int y, int u, int v) {
        if (r < x || u < l) return 0;
        pushDown();
        if (x <= l && r <= u) return node->getSum(y, v);
        return left->getSum(x, y, u, v) + right->getSum(x, y, u, v);
    }
};

int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    int foo, x, y, u, v, op;
    cin >> foo >> n;
    nodeX *root = new nodeX(0, n - 1);
    while (1) {
        cin >> op;
        if (op == 3) break;
        if (op == 1) {
            cin >> x >> y >> v;
            root->update(x, y, v);
        }
        else {
            cin >> x >> y >> u >> v;
            cout << root->getSum(x, y, u, v) << endl;
        }
    }
    return 0;
}

Code mẫu của RR

{$R+,Q+}
PROGRAM NKMOBILE;
CONST
  FINP='';
  FOUT='';
  maxn=1024;
VAR
  n,i1,i2,j1,j2,num:longint;
  f1,f2:text;
  t1,t2:array[1..maxn,1..maxn] of longint;
procedure openFiles;
begin
  assign(f1,FINP); reset(f1);
  assign(f2,FOUT); rewrite(f2);
end;
procedure closeFiles;
begin
  close(f1); close(f2);
end;
procedure updateT2(v,u:longint);
begin
  t2[v,u]:=t2[v,u]+num;
  u:=u+u and (1+not u);
  if u<=n then updateT2(v,u);
end;
procedure update2D(u,v:longint);
begin
  t1[u,v]:=t1[u,v]+num;
  updateT2(v,u);
  v:=v+v and (1+not v);
  if v<=n then update2D(u,v);
end;
function get(u,v:longint):longint;
var
  kq:longint;
begin
  kq:=t2[v,u];
  u:=u and (u-1);
  if u>0 then kq:=kq+get(u,v);
  get:=kq;
end;
function get2D(u,v:longint):longint;
var
  kq:longint;
begin
  kq:=get(u,v);
  v:=v and (v-1);
  if v>0 then kq:=kq+get2D(u,v);
  get2D:=kq;
end;
procedure solve;
var
  yc:byte;
begin
  readln(f1,yc,n);
  repeat
    read(f1,yc);
    if yc=1 then
      begin
        readln(f1,i1,j1,num);
        inc(i1); inc(j1);
        update2D(i1,j1);
      end
    else if yc=2 then
      begin
        readln(f1,i1,j1,i2,j2);
        inc(i2); inc(j2);
        num:=get2D(i2,j2);
        if (i1>0) and (j2>0) then num:=num-get2D(i1,j2);
        if (i2>0) and (j1>0) then num:=num-get2D(i2,j1);
        if (i1>0) and (j1>0) then num:=num+get2D(i1,j1);
        writeln(f2,num);
      end;
  until yc=3;
end;
BEGIN
  openFiles;
  solve;
  closeFiles;
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.000000001
#define maxn 10011
#define oo 1111111111
#define base 100000000
#define TR(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++)
double const PI=4*atan(1);

using namespace std;

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

int n,f[1111][1111];

void cong(int x,int y,int c){
     for(int ix = x;ix<=n;ix+=ix&-ix)
           for(int iy=y;iy<=n;iy+=iy&-iy)
                 f[ix][iy]+=c;
}

int tong(int x,int y){
     int kq = 0;
     for(int ix = x;ix>0;ix-=ix&-ix)
          for(int iy = y;iy>0;iy-=iy&-iy)
               kq+=f[ix][iy];
     return kq;
}

int tinh(int x1,int y1,int x2,int y2){
     return tong(x2,y2)-tong(x1-1,y2)-tong(x2,y1-1)+tong(x1-1,y1-1); 
}

int main(){
   //  freopen("NKMOBILE.in","r",stdin);
     int id,a,b,c,d;
     while(scanf("%d",&id)>0 && id!=3){
          if(id==0){
                scanf("%d",&n);
                memset(f,0,sizeof(f));
          }
          else if(id==1){
                scanf("%d %d %d",&a,&b,&c);
                cong(a+1,b+1,c);
          }
          else{
                scanf("%d %d %d %d",&a,&b,&c,&d);
                printf("%d\n",tinh(a+1,b+1,c+1,d+1));
          }
     } 
   //  getch();
}

Code mẫu của ll931110

#include <iostream>
#define MAX 1025
using namespace std;

int a[MAX][MAX];
int s,query;

void update(int x, int y, int val)
{
     int t;

     do
     {
         t = y;
         do
         {
             a[x][t] += val;
             t += t & -t;
         }
         while (t <= s);

         x += x & -x;
     }
     while (x <= s);
}

int calc(int x, int y)
{
    int res,t;

    res = 0;
    while (x > 0)
    {
      t = y;
      while (t > 0)
      {
            res += a[x][t];
            t -= t & -t;
      }

      x -= x & -x;
    }

    return res;
}

int main()
{
    int x1,y1,x2,y2,val,i,j;
    int k1,k2,k3,k4,k;

    //freopen("nkmobile.inp","r",stdin);
    //freopen("nkmobile.out","w",stdout);

    scanf("%d%d",&query,&s);
    for (i = 0; i <= s; i++)
      for (j = 0; j <= s; j++)
        a[i][j] = 0;

    do
    {
        scanf("%d",&query);
        if (query == 1)
          {
                  scanf("%d%d%d",&x1,&y1,&val);
                  x1++;
                  y1++;
                  update(x1,y1,val);
          }
        else if (query == 2)
          {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                x2++;
                y2++;

                k4 = calc(x2,y2);
                k3 = calc(x2,y1);
                k2 = calc(x1,y2);
                k1 = calc(x1,y1);
                k = k4 - k3 - k2 + k1;
                printf("%d\n",k);
          };
    }
    while (query != 3);
}

Code mẫu của skyvn97

#include<bits/stdc++.h>
#define MAX   1111
typedef long long ll;
int n;
ll a[MAX][MAX];
void add(int x,int y,const ll &val) {
    int t;
    while (1<=x && x<=n) {
        t=y;
        while (1<=t && t<=n) {
            a[x][t]+=val;
            t=t+(t&(-t));
        }
        x=x+(x&(-x));
    }
}
ll sum(int x,int y) {
    ll ret=0;
    int t;
    while (1<=x && x<=n) {
        t=y;
        while (1<=t && t<=n) {
            ret+=a[x][t];
            t=t&(t-1);
        }
        x=x&(x-1);
    }
    return (ret);
}
ll sum(const int &x1,const int &y1,const int &x2,const int &y2) {
    return (sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1));
}
void process(void) {
    scanf("%d",&n);
    scanf("%d",&n);
    int t,x1,y1,x2,y2;
    ll v;
    while (true) {
        scanf("%d",&t);
        if (t==3) return;
        if (t==1) {
            scanf("%d",&x1); x1++;
            scanf("%d",&y1); y1++;
            scanf("%lld",&v);
            add(x1,y1,v);
        }
        else {
            scanf("%d",&x1); x1++;
            scanf("%d",&y1); y1++;
            scanf("%d",&x2); x2++;
            scanf("%d",&y2); y2++;
            printf("%lld\n",sum(x1,y1,x2,y2));
        }
    }
}
int main(void) {
    process();
    return 0;
}

Code mẫu của khuc_tuan

var
   ad, x, y, u, v, i, j, code, n : integer;
   a : array[0..1023,0..1023] of longint;

function tinh(x,y:integer):longint;
var i,j:integer;
    r : longint;
begin
     i := x;
     r := 0;
     while i>=0 do begin
         j := y;
         while j>=0 do begin
              inc( r, a[i,j]);
              j := (j and (j+1)) - 1;
         end;
         i := (i and (i+1)) -1;
     end;
     tinh := r;
end;

begin
     while true do begin
         read(code);
         if code=0 then read(n)
         else if code=1 then begin
            read(x,y,ad);
            i := x; j := y;
            while i<n do begin
                 j := y;
                 while j<n do begin
                       inc(a[i,j], ad);
                       j := j or (j+1);
                  end;
                  i := i or (i+1);
            end;
         end
         else if code=2 then begin
             read(x,y,u,v);
             writeln(tinh(u,v)-tinh(u,y-1)-tinh(x-1,v)+tinh(x-1,y-1));
         end
         else break;
     end;
end.

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.