Submission #538763

#TimeUsernameProblemLanguageResultExecution timeMemory
538763perchutsCrayfish scrivener (IOI12_scrivener)C++17
100 / 100
649 ms67204 KiB
#include <bits/stdc++.h>
#define all(x) x.begin(), x.end()
#define sz(x) (int) x.size()
#define endl '\n'
#define pb push_back
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ii = pair<int,int>;
using iii = tuple<int,int,int>;

const int inf = 2e9+1;
const int mod = 1e9+7;
const int maxn = 1e5+100;
const int _log = 20;
template<typename X, typename Y> bool ckmin(X& x, const Y& y) { return (y < x) ? (x=y,1):0; }
template<typename X, typename Y> bool ckmax(X& x, const Y& y) { return (x < y) ? (x=y,1):0; }
vector<int>visited;
int lvl[10*maxn], par[10*maxn][_log], current = 1, parent = 0;
char letter[10*maxn];
void Init(){
    visited.pb(0);
    lvl[0] = -1;
    //model to a graph:
    //Every node represents a TypeLetter command.
    //Then we will have a tree.
    //TypeLetter will add a path from current node to a new node and we
    //will walk to this new node.
    //UndoCommands will return us to U-th last node visited 
    //GetLetter asks us for P-th first node in the path from root to current node.
    //To keep track of visited nodes, we can just use a vector.
    //we cant answer queries offline <:sad:835373614454407218>
    //its rather simple: binary lifting to answer GetLetter
    //to do this, we will only need an additional lvl array.
}

void TypeLetter(char l){
    // cout<<"typing letter "<<l<<" after "<<parent<<endl;
    letter[current] = l;
    par[current][0] = parent, lvl[current] = lvl[parent]+1;
    for(int i=1;i<_log;++i){
        if(par[current][i-1])par[current][i] = par[par[current][i-1]][i-1];
    }
    visited.pb(current);
    parent = current++;
}

void UndoCommands(int u){
    int commandsDone = sz(visited);
    parent = visited[commandsDone-1-u];
    visited.pb(parent);
    // cout<<"Complete list: ";
    // for(auto x:visited)cout<<x<<" ";
    // cout<<endl;
    // cout<<"undoing "<<u<<" commands and returning to node "<<parent<<endl;
}

char GetLetter(int target){
    // cout<<"currently at node "<<parent<<" and i want to go up by "<<target<<endl;
    if(target==lvl[parent]){
        // cout<<"found "<<parent<<" as target"<<" "<<letter[parent]<<endl;
        return letter[parent];
    }
    int cur = parent;
    for(int i=_log-1;~i;--i){
        if(lvl[par[cur][i]]>target)cur = par[cur][i];
    }
    cur = par[cur][0];
    // cout<<"found "<<cur<<" as target"<<" "<<letter[parent]<<endl;
    return letter[cur];
}

// int main() {
//   Init();

//   int tmp,cmd_num;
//   tmp = scanf("%d", &cmd_num);
//   assert(tmp == 1);

//   int i;
//   for (i = 0; i < cmd_num; i++) {
//     char cmd;
//     tmp = scanf(" %c", &cmd);
//     assert(tmp == 1);
//     if (cmd == 'T') {
//       char letter;
//       tmp = scanf(" %c", &letter);
//       assert(tmp == 1);
//       TypeLetter(letter);
//     }
//     else if (cmd == 'U') {
//       int number;
//       tmp = scanf("%d", &number);
//       assert(tmp == 1);
//       UndoCommands(number);
//     }
//     else if (cmd == 'P') {
//       int index;
//       char letter;
//       tmp = scanf("%d", &index);
//       assert(tmp == 1);
//       letter = GetLetter(index);
//       printf("%c\n", letter);
//     }
//   }
  
//   puts("Let's test for cheating!!");

//   return 0;

// }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...