Hướng dẫn giải của Chuyên gia ruồi


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='';
      maxn=400040;
var n,num,max:longint;
    aa,d,f:array[0..maxn] of longint;
    a:array[0..maxn shr 1] of longint;
    b:array[0..maxn shr 1,1..3] of longint;

procedure sort(l,r:longint);
var i,j,x,y:longint;
begin
     i:=l; j:=r; x:=aa[(i+j) shr 1];
     repeat
           while aa[i]<x do i:=i+1;
           while aa[j]>x do j:=j-1;
           if i<=j then
           begin
                y:=aa[i]; aa[i]:=aa[j]; aa[j]:=y;
                y:=d[i]; d[i]:=d[j]; d[j]:=y;
                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;

procedure rf;
var i,j:longint; c:char;
begin
     readln(n);
     for i:=1 to n do
     begin
          read(c);
          if c<>'?' then
          begin
               readln(a[i]);
               num:=num+1;
               aa[num]:=a[i];
               d[num]:=i;
               if c='-' then a[i]:=-a[i];
          end
          else
          begin
               for j:=1 to 3 do read(b[i,j]);
               num:=num+2;
               aa[num-1]:=b[i,2]; d[num-1]:=-i;
               aa[num]:=b[i,3]; d[num]:=i;
               readln;
          end;
     end;
end;

procedure edit;
var i:longint;
begin
     max:=0;
     for i:=1 to num do
     begin
          if aa[i]<>aa[max] then
          begin
               inc(max);
               aa[max]:=aa[i];
          end;
          if a[abs(d[i])]<>0 then
          begin
               if a[d[i]]>0 then a[d[i]]:=max
               else a[d[i]]:=-max;
          end
          else
          begin
               if d[i]<0 then b[-d[i],2]:=max
               else b[d[i],3]:=max;
          end;
     end;
end;

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

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

procedure pr;
var i,t,l,r,m,u,j:longint;
begin
     sort(1,num);
     edit;
     for i:=1 to n do
         if a[i]<>0 then
         begin
              if a[i]>0 then add(a[i],1)
              else add(-a[i],-1);
         end
         else
         begin
            t:=calc(b[i,2]-1)+b[i,1];
            l:=b[i,2]; r:=b[i,3];
            if calc(r)<t then writeln(0)
            else
            begin
               while l<=r do
               begin
                    m:=(l+r) shr 1;
                    u:=calc(m);
                    if u<t then l:=m+1
                    else r:=m-1;
               end;
               for j:=m-1 to m+1 do
                   if (j>=b[i,2]) and (j<=b[i,3]) and (calc(j)>=t) then break;
               writeln(aa[j]);
            end;
         end;
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 X first
#define Y second
const int N = 200005;
const int add = 1;
const int del = -1;
const int cnt = 2;
struct e {
    int type, a, b, k;
};
using namespace std;
e event[N];
ii b[N];
int mirror[N], bit[N];
int n, m, d;

int BS(int key) {
    int l = 0, r = d, k = 0, m;
    while (l <= r) {
        m = (l + r) >> 1;
        if (mirror[m] <= key) {
            k = m; l = m + 1;
        }
        else
            r = m - 1;
    }
    return k;
}

void Upd(int i, int v) {
    while (i <= d) {
        bit[i] += v;
        i += i & (-i);
    }
}

int Get(int i) {
    int s = 0;
    while (i) {
        s += bit[i];
        i -= i & (-i);
    }
    return s;
}

void Enter() {
    scanf("%d\n", &n);
    int i; char c;

    for(i=1; i<=n; i++) {
        scanf("%c ", &c);
        if (c == '+') {
            event[i].type = add;
            scanf("%d\n", &event[i].a);
            b[++m] = ii(event[i].a, i);
        }
        if (c == '-') {
            event[i].type = del;
            scanf("%d\n", &event[i].a);
            b[++m] = ii(event[i].a, i);
        }
        if (c == '?') {
            event[i].type = cnt;
            scanf("%d %d %d\n", &event[i].k, &event[i].a, &event[i].b);
        }
    }
    sort(b+1, b+1+m);
    for(i=1; i<=m; i++) {
        if (b[i].X != b[i-1].X) d++;
        event[b[i].Y].a = d;
        mirror[d] = b[i].X;
    }
}

void Answer() {
    int i, L, R, mid, VL, res;
    for(i=1; i<=n; i++) {
        if (event[i].type != cnt)
            Upd(event[i].a, event[i].type);
        else {
            L = BS(event[i].a - 1);
            R = BS(event[i].b);
            VL = Get(L);
            if (R == 0 || Get(R) - VL < event[i].k) {
                printf("0\n"); continue;
            }
            while (L <= R) {
                mid = (L + R) >> 1;
                if (Get(mid) - VL >= event[i].k) {
                    res = mid;
                    R = mid - 1;
                }
                else
                    L = mid + 1;
            }
            printf("%d\n", mirror[res]);
        }
    }
}

int main()
{
    Enter();
    Answer();
    return 0;
}

Code mẫu của RR

{$IFDEF NORMAL}
  {$H-,I+,OBJECTCHECKS-,Q+,R+,S+}
{$ENDIF NORMAL}
{$IFDEF DEBUG}
  {$H-,I+,OBJECTCHECKS-,Q+,R+,S+}
{$ENDIF DEBUG}
{$IFDEF RELEASE}
  {$H-,I-,OBJECTCHECKS-,Q-,R-,S-}
{$ENDIF RELEASE}
uses math;
const
  fin ='';
  fout='';
  maxquest=222222;
  maxage=maxquest;

type
  quest_data=record ch:char; x,y,z:longint end;
  it_tree=array[0..maxage*4] of longint;

var
  fi,fo:text;
  nage:longint;
  age:array[0..maxage] of longint;
  pos_age:array[0..maxage] of longint;
  real_age:array[0..maxage] of longint;
  que:array[0..maxquest] of quest_data;
  nque:longint;
  it:it_tree;
  left,right,res,count:longint;

procedure enter;
  var
    i:longint;
  begin
    readln(Fi,nque);
    for i:=1 to nque do
      begin
        read(Fi,que[i].ch);
        case que[i].ch of
          '+','-': readln(fi,que[i].x);
          '?':readln(fi,que[i].x,que[i].y,que[i].z);
        end;
      end;
  end;

procedure init;
  begin
    filldword(it,sizeof(it) div 4,0);
  end;

procedure make_age;
  var
    i:longint;
  begin
    nage := 0;
    for i:=1 to nque do
      begin
        if (que[i].ch = '+') or (que[i].ch = '-') then
          begin
            inc(nage);
            age[nage] := que[i].x;
            pos_age[nage] := i;
          end;
      end;
  end;

procedure swap(var x,y:longint);
  var
    tg:longint;
  begin
    tg:=x;
    x:=y;
    y:=tg;
  end;

procedure quicksort(l,h:longint);
  var
    i,j,pivot:longint;
  begin
    if l >= h then exit;
    i := l;
    j := h;
    pivot := age[random(h-l+1) + l];

    repeat
      while age[i] < pivot do inc(i);
      while age[j] > pivot do dec(j);
      if i <= j then
        begin
          swap(age[i],age[j]);
          swap(pos_age[i],pos_age[j]);
          inc(i);
          dec(J);
        end;
    until i > j;

    quicksort(l,j);
    quicksort(i,h);
  end;

procedure roirac_age;
  var
    i,nn:longint;
  begin
    quicksort(1,nage);

    nn:=1;
    real_age[1] := age[1];
    que[pos_age[1]].x := 1;

    for i:=2 to nage do
      if age[i] > age[i-1] then
        begin
          inc(nn);
          real_age[nn] := age[i];
          que[pos_age[i]].x := nn;
        end
      else que[pos_age[i]].x := nn;

    nage := nn;
  end;

procedure update(k,l,h,x,val:longint);
  var
    mid:longint;
  begin
    if (l > h) or (l > x) or (h < x) then exit;
    if (l = h) then
      begin
        if l = x then it[k] := it[k] + val;
        exit;
      end;

    mid := (l+h) div 2;

    update(k*2,l,mid,x,val);
    update(k*2+1,mid+1,h,x,val);

    it[k] := it[k*2] + it[k*2+1];
  end;

procedure get(k,l,h:longint);
  var
    mid:longint;
  begin
    if (res <> 0) or (l > h) or (left > right)
      or (real_age[h] < left) or (real_age[l] > right) then exit;

    mid := (l+h) div 2;

    if (left <= real_age[l]) and (real_age[h] <= right) then
      begin
        if (l = h) and (it[k] >= count) then
          begin
            res := real_age[l];
            count := 0;
            exit;
          end;

        if it[k] < count then
          begin
            count := count - it[k];
            exit;
          end;

        get(k*2,l,mid);
        get(k*2+1,mid+1,h);
        exit;
      end;

    mid := (l+h) div 2;
    get(k*2,l,mid);
    get(k*2+1,mid+1,h);
  end;

procedure solve;
  var
    i:longint;
  begin
    for i:=1 to nque do
      case que[i].ch of
        '+':
          begin
            update(1,1,nage,que[i].x,1);
          end;
        '-':
          begin
            update(1,1,nage,que[i].x,-1);
          end;
        '?':
          begin
            count := que[i].x;
            left := que[i].y;
            right := que[i].z;
            res := 0;

            get(1,1,nage);

            writeln(fo,res);
          end;
        end;
  end;

begin
  assign(Fi,fin);reset(fi);
  assign(fo,fout);rewrite(Fo);

  enter;
  init;
  make_age;
  roirac_age;
  solve;

  close(Fo);close(Fi);
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 200011
#define mod 1000000000
#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;

const int MAXN = 18;
int tr[MAXN + 1][1 << MAXN] = {0}, f[maxn] = {0};
void insert(int x){ for(int i = 0; i <= MAXN; i++) tr[i][x]++, x >>= 1;}
void eraser(int x){ for(int i = 0; i <= MAXN; i++) tr[i][x]--, x >>= 1;}
int kThElement(int k){
    int a = 0, b = MAXN;
    while(b--) a <<= 1, k -= ( tr[b][a] < k ? tr[b][a++] : 0);
    return a;
}

void update(int u, int gt)
{
    while(u <= 200000){
        f[u] += gt;
        u += u & -u;
    }
}

int get(int u){
    int res = 0;
    while(u > 0){
        res += f[u];
        u -= u & -u;
    }
    return res;
}

int k[maxn] = {0}, b[maxn], a[maxn], rea[maxn], n, run , u , v;
pair<int, int> t[maxn];
char s[200002][2];

int main(){
   // freopen("input.in","r",stdin); 
   // freopen("output.out","w",stdout);
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        scanf("%s", s[i]);
        if(s[i][0] == '?'){
            scanf("%d %d %d", &k[i], &t[i].fi, &b[i]);
        }
        else scanf("%d", &t[i].fi);
        t[i].se = i;
    }

    sort(t, t + n);
    a[t[0].se] = 1;
    for(int i = 1; i < n; i++){
        if(t[i].fi > t[i - 1].fi) a[t[i].se] = a[t[i - 1].se] + 1;
        else a[t[i].se] = a[t[i - 1].se];
        rea[a[t[i].se]] = t[i].fi;
    }
    run = 0;
    for(int i = 0; i < n; i++){
        if(s[i][0] == '?'){
            u = k[i] + get(a[i] - 1); 
            if(u > run) printf("0\n");
            else{
                v = kThElement(u);
                if(rea[v] > b[i]) printf("0\n");
                else printf("%d\n",rea[v]);
            }
        }
        else if(s[i][0] == '+'){
            insert(a[i]);
            update(a[i], 1);
            run++;
        }
        else{
            eraser(a[i]);
            update(a[i], -1);
            run--;
        }
    }
}

Code mẫu của ll931110

{$MODE DELPHI}
program FOCUS;
const
  input  = '';
  output = '';
  maxn = 200010;
var
  q,pos: array[1..3 * maxn] of integer;
  a,b,t: array[1..2 * maxn] of integer;
  ch: array[1..maxn] of char;
  n,num: integer;
  fi,fo: text;

procedure add(i: integer);
begin
  read(fi, q[i]);
  inc(num);
  a[num] := q[i];
  pos[num] := i;
end;

procedure init;
var
  i: integer;
begin
  assign(fi, input);
    reset(fi);

  readln(fi, n);
  num := 0;
  for i := 1 to n do
    begin
      read(fi, ch[i]);
      if ch[i] = '?' then
        begin
          read(fi, q[3 * i]);
          add(3 * i + 1);
          add(3 * i + 2);
        end
      else add(3 * i);
      readln(fi);
    end;

  close(fi);
end;

procedure swap(var x,y: integer);
var
  tmp: integer;
begin
  tmp := x;  x := y;  y := tmp;
end;

procedure swapint(i,j: integer);
begin
  swap(a[i],a[j]);
  swap(pos[i],pos[j]);
end;

procedure quicksort;

  procedure partition(l,h: integer);
  var
    i,j,p: integer;
  begin
    if l >= h then exit;
    i := l;  j := h;  p := a[random(h - l + 1) + l];

    repeat
      while a[i] < p do inc(i);
      while a[j] > p do dec(j);

      if i <= j then
        begin
          if i < j then swapint(i,j);
          inc(i);
          dec(j);
        end;
    until i > j;

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

var
  i,c: integer;
begin
  partition(1,num);
  c := 1;
  q[pos[1]] := 1;
  b[1] := a[1];

  for i := 2 to num do
    begin
      if a[i] > a[i - 1] then inc(c);
      q[pos[i]] := c;
      b[c] := a[i];
    end;
end;

procedure update(x,k: integer);
begin
  while x <= 2 * maxn do
    begin
      t[x] := t[x] + k;
      x := x + (x and -x);
    end;
end;

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

procedure solve;
var
  i,inf,sup,mid,tmp,tm,res: integer;
begin
  assign(fo, output);
    rewrite(fo);

  for i := 1 to n do
    if ch[i] = '+' then update(q[3 * i],1)
    else if ch[i] = '-' then update(q[3 * i],-1)
    else
      begin
        inf := q[3 * i + 1];
        sup := q[3 * i + 2];

        if calc(sup) - calc(inf - 1) < q[3 * i] then writeln(fo, 0) else
          begin
            tmp := calc(inf - 1);
            repeat
              mid := (inf + sup) div 2;
              tm := calc(mid);

              if tm < q[3 * i] + tmp then inf := mid + 1 else
                begin
                  res := mid;
                  sup := mid - 1;
                end;
            until inf > sup;

            writeln(fo, b[res]);
          end;
      end;

  close(fo);
end;

begin
  init;
  quicksort;
  solve;
end.

Code mẫu của khuc_tuan

#include <iostream>
#include <iomanip>
#include <fstream>
#include <set>
#include <map>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#include <cstring>
#include <string>
#include <sstream>
#include <algorithm>
#include <functional>
#include <ctime>
#include <cstdio>
#include <cstdarg>

using namespace std;

#define Rep(i,n) for(int i=0;i<(n);++i)
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Ford(i,a,b) for(int i=(a);i>=(b);--i)
#define Fill(a,b) memset( (a), (b), sizeof(a))
#define pb push_back
#define MP make_pair
#define fi first
#define se second

typedef pair<int,int> PII;
typedef pair<PII,PII> PP;

const int MAXN = 200020;

char buf[1000];
PP command[MAXN];
int dx[MAXN], nd;
int sum[MAXN * 4];

void add(int n, int l, int r, int pos, int v) {
    sum[n] += v;
    if(l == r) return;
    int m = (l+r) / 2;
    if(pos <= m) add( 2*n, l, m, pos, v);
    else add( 2*n+1, m+1, r, pos, v);
}

void find(int n, int l, int r, int a, int b, int &k, int &pos) {
    if(k == 0) return;
    if(a <= l && r <= b) {
        if(k > sum[n]) {
            k -= sum[n];
            return;
        }
    }
    if(l == r) {
        k = 0;
        pos = l;
        return;
    }
    int m = (l+r) / 2;
    if(a <= m) find( 2*n, l, m, a, b, k, pos);
    if(m < b) find( 2*n+1, m+1, r, a, b, k, pos);
}

int main() {
    int m;
    scanf("%d", &m);
    gets(buf);
    Rep(kk,m) {
        int x, a, b;
        gets(buf);
        if(buf[0] == '+') {
            sscanf( buf + 1, "%d", &x);
            command[kk] = MP(MP(1,x),MP(0,0));
            dx[nd++] = x;
        }
        else if(buf[0] == '-') {
            sscanf( buf + 1, "%d", &x);
            command[kk] = MP(MP(2,x),MP(0,0));
            dx[nd++] = x;
        }
        else {
            sscanf( buf + 1, "%d%d%d", &x, &a, &b);
            command[kk] = MP(MP(3,x), MP(a,b));
        }
    }   
    sort( dx, dx + nd);
    nd = unique( dx, dx + nd) - dx;

    Rep(k,m) {
        if(command[k].fi.fi == 1) {
            int pos = lower_bound( dx, dx + nd, command[k].fi.se) - dx;
            add( 1, 0, nd - 1, pos, 1);
        }
        else if(command[k].fi.fi == 2) {
            int pos = lower_bound( dx, dx + nd, command[k].fi.se) - dx;
            add( 1, 0, nd - 1, pos, -1);
        }
        else {
            int a, b;
            int kk = command[k].fi.se;
            a = lower_bound( dx, dx + nd, command[k].se.fi) - dx;
            b = upper_bound( dx, dx + nd, command[k].se.se) - dx;
            --b;

            if(a <= b) {
                int pos = -1;
                find( 1, 0, nd - 1, a, b, kk, pos);
                if(pos == -1) printf("0\n");
                else printf("%d\n", dx[pos]);
            }
            else printf("0\n");
        }
    }
    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.