# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
105911 | nvmdava | Jousting tournament (IOI12_tournament) | C++17 | 0 ms | 0 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define N 131075
int n;
int r[N];
int lef[N][20];
int logg[N];
void fillsparse(){
for(int i = 1; i <= n; i++){
lef[i][0] = r[i];
for(int j = 1; j < 20; j++){
if(i < (1 << j))
break;
lef[i][j] = max(lef[i][j - 1], lef[i - (1 << (j - 1))][j - 1]);
}
}
logg[1] = 0;
for(int i = 2; i <= 131072; i++)
logg[i] = logg[i / 2] + 1;
}
int getmin(int l, int r){
int sz = logg[r - l + 1];
return max(lef[r][sz], lef[l + (1 << sz) - 1][sz]);
}
struct Fen{
int arr[N];
void update(int id, int val){
for(; id < N; id += id & -id)
arr[id] += val;
};
int sum(int id){
int res = 0;
while(id){
res += arr[id];
id -= id & -id;
}
return res;
}
} fen;
int segTree[2 * N];
#define MX 131072
void update(int id, int l, int r, int L, int R){
if(l == L && r == R){
segTree[id]++;
return;
}
int m = (l + r) >> 1;
if(m < L) update(id << 1 | 1, m + 1, r, L, R);
else if(m >= R) update(id << 1, l, m, L, R);
else {
update(id << 1, l, m, L, m);
update(id << 1 | 1, m + 1, r, m + 1, R);
}
}
typedef tree<pair<int, int>, null_type, less_equal<pair<int, int>>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
ordered_set pos;
int GetBestPosition(int NN, int C, int R, int *K, int *S, int *E) {
n = NN;
pos.insert({0, 0});
for(int i = 1; i < n; i++){
r[i] = S[i - 1];
pos.insert({i, i});
}
pos.insert({n, n});
r[n] = -1;
fillsparse();
// cout<<'\n';
for(int i = 0; i < C; i++){
int add1 = 0, add2 = 0;
S[i]++;
E[i]++;
int lst = (*pos.find_by_order(E[i])).second;
int beg = (*pos.find_by_order(S[i])).first;
for(; E[i] >= S[i]; E[i]--){
pos.erase(pos.find_by_order(E[i]));
}
E[i] = lst;
S[i] = beg;
pos.insert({beg, lst});
// cout<<S[i]<<' '<<E[i]<<'\n';
if(getmin(S[i], E[i] - 1) < R){
update(1, 1, MX, S[i], E[i]);
}
}
// cout<<'\n';
for(int i = 1; i < MX; i++){
segTree[i << 1] += segTree[i];
segTree[i << 1 | 1] += segTree[i];
}
int best = 0;
for(int i = 1; i < n; i++){
if(segTree[MX + i] > segTree[MX + best]){
best = i;
}
}
/*
for(int i = 0; i < n; i++){
cout<<i<<' '<<segTree[i + MX]<<'\n';
}
*/
return best;
}
/*
#define inbuf_len 1 << 16
#define outbuf_len 1 << 16
int GetBestPosition(int NN, int C, int R, int *K, int *S, int *E);
int main() {
int tmp;
/* Set input and output buffering */
char *inbuf, *outbuf;
inbuf = (char*) malloc(inbuf_len * sizeof(char));
outbuf = (char*) malloc(outbuf_len * sizeof(char));
int NN, C, R;
int *K, *S, *E;
tmp = scanf("%d %d %d", &NN, &C, &R);
K = (int*) malloc((NN-1) * sizeof(int));
S = (int*) malloc(C * sizeof(int));
E = (int*) malloc(C * sizeof(int));
int i;
for (i = 0; i < NN-1; i++) {
tmp = scanf("%d", &K[i]);
assert(tmp == 1);
}
for (i = 0; i < C; i++) {
tmp = scanf("%d %d", &S[i], &E[i]);
assert(tmp == 2);
}
printf("\n%d\n", GetBestPosition(NN, C, R, K, S, E));
return 0;
}
*/