Advertisement
999ms

Untitled

Mar 24th, 2019
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.36 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <bits/stdc++.h>
  4.  
  5. namespace FastIO {
  6.     struct Reader {
  7.         private:
  8.             FILE* file; std::vector<char> buffer; int pos;
  9.             void read();
  10.             bool was;
  11.         public:
  12.             Reader(FILE* file_ = stdin, const int size_ = 1 << 16)
  13.                 : file(file_), buffer(size_, '\0'), pos(size_), was(true) { }
  14.             operator bool() const { return was; }
  15.             char getChar();
  16.             std::string getStr();
  17.             std::string getLine();
  18.             template<typename T> T getInt();
  19.             template<typename T> T getReal();
  20.     };
  21.    
  22.     Reader& operator>>(Reader& reader, char& c) { return c = reader.getChar(), reader; }
  23.    
  24.     Reader& operator>>(Reader& reader, std::string& s) { return s = reader.getStr(), reader; }
  25.    
  26.     template<class T> typename std::enable_if<std::is_floating_point<T>::value, Reader&>::type
  27.     operator>>(Reader& reader, T& t) { return t = reader.getReal<T>(), reader; }
  28.    
  29.     template<class T> typename std::enable_if<std::is_integral<T>::value, Reader&>::type
  30.     operator>>(Reader& reader, T& t) { return t = reader.getInt<T>(), reader; }
  31.    
  32.     template<class T> Reader& operator>>(Reader& reader, std::vector<T>& vec) {
  33.         for (auto &it : vec) { reader >> it; }
  34.         return reader;
  35.     }
  36.    
  37.     struct Writer {
  38.         private:
  39.             FILE* file; std::vector<char> buffer; int pos;
  40.             int defaultPrecision, defaultWidth; char defaultFill;
  41.         public:
  42.             Writer(FILE* file_ = stdout, const int size_ = 1 << 16)
  43.                 : file(file_), buffer(size_, '\0'), pos(0), defaultPrecision(6), defaultWidth(0), defaultFill(' ') { }
  44.             ~Writer() { flush(); }
  45.             void flush() { putChar(EOF); }
  46.             void setprecision(int precision) { defaultPrecision = precision; }
  47.             void setw(int width) { defaultWidth = width; }
  48.             void setfill(char fill) { defaultFill = fill; }
  49.             int getPrecision() const { return defaultPrecision; }
  50.             int getWidth() const { return defaultWidth; }
  51.             char getFill() const { return defaultFill; }
  52.             void putChar(char c);
  53.             void putStr(const std::string&);
  54.             template<typename T> void putInt(T value, int width = 0, char fill = ' ');
  55.             template<typename T> void putReal(T value, int precision = 6, int width = 0, char fill = ' ');
  56.     };
  57.    
  58.     Writer& operator<<(Writer& writer, const char c) { return writer.putChar(c), writer; }
  59.    
  60.     Writer& operator<<(Writer& writer, const std::string& s) { return writer.putStr(s), writer; }
  61.    
  62.     template<class T> typename std::enable_if<std::is_floating_point<T>::value, Writer&>::type
  63.     operator<<(Writer& writer, const T& t) {
  64.         writer.putReal(t, writer.getPrecision(), writer.getWidth(), writer.getFill());
  65.         return writer;
  66.     }
  67.    
  68.     template<class T> typename std::enable_if<std::is_integral<T>::value, Writer&>::type
  69.     operator<<(Writer& writer, const T& t) {
  70.         writer.putInt(t, writer.getWidth(), writer.getFill());
  71.         return writer;
  72.     }
  73. }
  74.  
  75. namespace FastIO {
  76.        
  77.     void Reader::read() {
  78.         if (!buffer.empty()) {
  79.             buffer.resize(fread(&buffer[0], 1, (int)buffer.size(), file)); pos = 0;
  80.         }
  81.     }
  82.        
  83.     char Reader::getChar() {
  84.         if (pos == (int)buffer.size()) { read(); }
  85.         if (pos == (int)buffer.size()) { was = false; return EOF; }
  86.         else { was = true; return buffer[pos++]; }
  87.     }
  88.        
  89.     std::string Reader::getStr() {
  90.         char c = ' ';
  91.         while (std::isspace(c)) { c = getChar(); }
  92.         std::string answ;
  93.         while (c != EOF && !std::isspace(c)) { answ.push_back(c); c = getChar(); }
  94.         was = !answ.empty();
  95.         return answ;
  96.     }
  97.    
  98.     std::string Reader::getLine() {
  99.         char c = '\n';
  100.         while (c == '\n') { c = getChar(); }
  101.         std::string answ;
  102.         while (c != '\n' && c != EOF) { answ.push_back(c); c = getChar(); }
  103.         was = !answ.empty();
  104.         return answ;
  105.     }
  106.        
  107.     template<typename T>
  108.     T Reader::getInt() {
  109.         char c = '?';
  110.         while (!(c == '-' || ('0' <= c && c <= '9') || c == EOF)) { c = getChar(); }
  111.         bool positive = true;
  112.         if (c == '-') { positive = false; c = getChar(); }
  113.         T answ(0);
  114.         bool flag = false;
  115.         while ('0' <= c && c <= '9') { flag = true; (answ *= 10) += (c - '0'); c = getChar(); }
  116.         was = flag;
  117.         return positive ? answ : -answ;
  118.     }
  119.    
  120.     template<typename T>
  121.     T Reader::getReal() {
  122.         bool flag = false;
  123.         char c = '?';
  124.         while (!(c == '-' || ('0' <= c && c <= '9') || c == EOF)) { c = getChar(); }
  125.         bool positive = (c != '-');
  126.         if (c == '-') { c = getChar(); }
  127.         long long first = 0;
  128.         while ('0' <= c && c <= '9') { flag = true; (first *= 10) += (c - '0'); c = getChar(); }
  129.         was = flag;
  130.         if (c != '.') { return T(positive ? first : -first); }
  131.         c = getChar();
  132.         long long second = 0, pow = 1;
  133.         while ('0' <= c && c <= '9') { (second *= 10) += (c - '0'); c = getChar(); pow *= 10; }
  134.         T answ = first + (T)second / (T)pow;
  135.         return positive ? answ : -answ;
  136.     }
  137.    
  138.     void Writer::putChar(char c) {
  139.         if (pos == (int)buffer.size() || c == EOF) {
  140.             fwrite(&buffer[0], 1, pos, file); pos = 0;
  141.         }
  142.         if (c != EOF) { buffer[pos++] = c; }
  143.     }
  144.    
  145.     void Writer::putStr(const std::string& s) {
  146.         for (auto it : s) {
  147.             putChar(it);
  148.         }
  149.     }
  150.    
  151.     template<typename T>
  152.     void Writer::putInt(T value, int width, char fill) {
  153.         bool positive = !(value < 0);
  154.         if (value < 0) { value = -value; }
  155.         char buf[24]; int p = 0;
  156.         do { buf[p++] = char(value % 10 + '0'); value /= 10; } while (value > 0);
  157.         if (!positive) { buf[p++] = '-'; }
  158.         while (p < width) buf[p++] = fill;
  159.         while (p > 0) putChar(buf[--p]);
  160.     }
  161.    
  162.     template<typename T>
  163.     void Writer::putReal(T value, int precision, int width, char fill) {
  164.         putInt((long long)value, width - precision - 1, fill);
  165.         value = std::abs(value-(long long)value);
  166.         if (precision == 0) { return; }
  167.         putChar('.');
  168.         #define PRINT_PART(cnt, pow) \
  169.             while (precision >= cnt) { \
  170.                 value *= pow; \
  171.                 putInt((int)value, cnt, '0'); \
  172.                 value -= (int)value; \
  173.                 precision -= cnt; \
  174.             }
  175.         PRINT_PART(6,1000000)
  176.         PRINT_PART(3,1000)
  177.         PRINT_PART(1,10)
  178.         #undef PRINT_PART
  179.     }
  180. }
  181. typedef long long ll;
  182. const int sz = 500500;
  183. std::vector<int> g[sz];
  184. int t[sz<<2];
  185. int depth[sz];
  186. std::vector<int> lel;
  187. std::vector<int> kek;
  188. int n=0,q;
  189. std::vector<std::pair<int,int> > query;
  190. void dfs(int f, int p=-1, int h=1){
  191.     depth[f] = h;
  192.     lel.push_back(f);
  193.     for(int i : g[f]){
  194.         if(i != p){
  195.             dfs(i, f, h+1);
  196.             lel.push_back(f);
  197.         }
  198.     }
  199. }
  200.  
  201. void build(int v, int l, int r){
  202.     if(l == r){
  203.         t[v] = lel[l];
  204.     } else {
  205.         int m = (l+r)/2;
  206.         build(v*2, l, m);
  207.         build(v*2+1, m+1, r);
  208.         if(depth[t[v*2]] < depth[t[v*2+1]]){
  209.             t[v] = t[v*2];
  210.         } else {
  211.             t[v] = t[v*2+1];
  212.         }
  213.     }
  214. }
  215.  
  216. void init(){
  217.     depth[sz-1] = 1e9;
  218.     dfs(0);
  219.     build(1,0,lel.size()-1);
  220.     kek.assign(n, 1e9);
  221.     for(int i=0;i<lel.size();i++){
  222.         kek[lel[i]] = std::min(i, kek[lel[i]]);
  223.     }
  224. }
  225.  
  226. int lca(int v, int l, int r, int tl, int tr){
  227.     if(l > r) return sz-1;
  228.     if(tl == l && tr == r){
  229.         return t[v];
  230.     } else {
  231.         int tm = (tl + tr)/2;
  232.         int left_ans = lca(v*2, l, std::min(r, tm) , tl, tm);
  233.         int right_ans= lca(v*2+1, std::max(l, tm+1), r, tm+1, tr);
  234.         if(depth[left_ans] > depth[right_ans]) return right_ans;
  235.         return left_ans;
  236.     }
  237. }
  238.    
  239. int main(){
  240.         freopen("lca.in","r", stdin);
  241.         freopen("lca.out","w",stdout);
  242.         FastIO::Reader cin;
  243.         FastIO::Writer cout;
  244.     std::string type;
  245.     int a,b;
  246.     cin>>q;
  247.     for(int i=0;i<q;i++){
  248.         cin>>type>>a>>b;
  249.         n = std::max({a,b,n});
  250.         if(type[0] == 'A'){
  251.             g[a-1].push_back(b-1);
  252.             g[b-1].push_back(a-1);
  253.         } else {
  254.             query.push_back(std::make_pair(a-1,b-1));
  255.         }
  256.     }
  257.     init();
  258.     for(auto [a,b] : query){
  259.         a = kek[a];
  260.         b = kek[b];
  261.         if(a > b) std::swap(a,b);
  262.         cout<<1 + lca(1, a, b, 0, lel.size()-1)<<"\n";     
  263.     }
  264.     return 0;
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement