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.
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