Problem:
Chemical Substance Alpha
At Aizu Pharmaceutical, we are constantly researching chemical substances. The chemical we are currently researching is code-named "alpha," which has a structure consisting of molecules numbered $1$ through $N$ arranged in a straight line from leftmost to rightmost.
Using the technology developed by Aizu Pharmaceuticals, the positions of the molecules that make up Alpha can be swapped. The swapping can only be done in a fixed procedure, but it can also be started and finished in the middle of that procedure. Let's write (a,b) for the operation of swapping the a-th and b-th molecules from the left end. For example, if $N=5$ and the fixed sequence is (1,3),(2,5),(4,3),(1,5), you can start with the first operation (1,3) and end with the third operation (4,3), or you can start with the second operation (2,5) and end with the fourth operation (1,5).
You have chosen the start and end positions in the alpha molecule replacement procedure to run the simulation and investigate the state of the molecule after the replacement.
You are given an alpha molecular replacement procedure. Write a program that answers questions about the position of the molecule in each simulation when you run the simulation several times. The questions can be of the form 1. or 2. below.
What was the initial position of the molecule that is the i-th position from the left end after the end of the simulation?
What position does the molecule that was initially positioned i-th come to after termination?
Note that each simulation starts from the initial state of alpha (molecules numbered $1$ to $N$ are lined up in a straight line from the leftmost to the rightmost position).
Input
The input is given in the following form.
$N$ $K$ $Q$
$a_1$ $b_1$
$a_2$ $b_2$
:
$a_K$ $b_K$
$query_1$
$query_2$
:
$query_Q$
The first line gives the number of molecules in alpha $N$ ($2 \leq N \leq 100,000$), the length of the swapping procedure $K$ ($1 \leq K \leq 100,000$), and the number of times to check the state of the molecules after swapping $Q$ ($1 \leq Q \leq 100,000$). In the following $K$ lines, each operation $a_i,b_i$ ($1 \leq a_i,b_i\leq N, a_i \ne b_i$) in the transposition procedure is given. $i$-th operation represents the operation to transpose the $a_i$-th and $b_i$-th molecules from the left end. In the following $Q$ lines, questions are given asking the state of the molecules after the swap. Each $query_i$ is given in one of the following forms.
1 $s$ $t$ $x$
or
2 $s$ $t$ $x$
If the first number is 1, it represents a question that asks what the number of the $x$-th molecule from the left side ($1 \leq x \leq N$) is after performing the transposition from $s$-th to $t$-th ($1 \leq s \leq t \leq K$) in the transposition procedure. If the first number is 2, it represents a question that asks where is the $x$-th ($1 \leq x \leq N$) molecule from the left side after performing the transposition in the transposition procedure from $s$-th to $t$-th ($1 \leq s \leq t \le
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, e) for (int i = (int)(s); i < (int)(e); ++i)

int main() {
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);
	
	int N, K, Q;
	cin >> N >> K >> Q;
	
	int Bsiz = sqrt(K) + 1;
	vector<vector<pair<int, int>>> B(Bsiz);
	rep(i, 0, K) {
		int a, b;
		cin >> a >> b;
		--a, --b;
		B[i / Bsiz].push_back({a, b});
	}
	
	vector<unordered_map<int, int>> nex(Bsiz), pre(Bsiz);
	rep(i, 0, Bsiz) {
		int siz = B[i].size();
		rep(j, 0, siz) {
			if (!nex[i].count(B[i][j].first)) nex[i][B[i][j].first] = B[i][j].first;
			if (!nex[i].count(B[i][j].second)) nex[i][B[i][j].second] = B[i][j].second;
			swap(nex[i][B[i][j].first], nex[i][B[i][j].second]);
		}
		for (int j = siz - 1; j >= 0; --j) {
			if (!pre[i].count(B[i][j].first)) pre[i][B[i][j].first] = B[i][j].first;
			if (!pre[i].count(B[i][j].second)) pre[i][B[i][j].second] = B[i][j].second;
			swap(pre[i][B[i][j].first], pre[i][B[i][j].second]);
		}
	}
	
	rep(query, 0, Q) {
		int ord, s, t, x;
		cin >> ord >> s >> t >> x;
		--s, --t, --x;
		
		int res = x;
		if (ord == 1) {
			if (s / Bsiz == t / Bsiz) {
				for (int i = t; i >= s; --i) {
					if ((res == B[s/Bsiz][i%Bsiz].first)) res = B[s/Bsiz][i%Bsiz].second;
					else if ((res == B[s/Bsiz][i%Bsiz].second)) res = B[s/Bsiz][i%Bsiz].first;
				}
			} else {
				while (true) {
					if ((res == B[t/Bsiz][t%Bsiz].first)) res = B[t/Bsiz][t%Bsiz].second;
					else if ((res == B[t/Bsiz][t%Bsiz].second)) res = B[t/Bsiz][t%Bsiz].first;
					--t;
					if (t % Bsiz == Bsiz - 1) break;
				}
				
				while (true) {
					if (s / Bsiz == t / Bsiz) break;
					if (nex[t/Bsiz].count(res)) res = nex[t/Bsiz][res];
					t -= Bsiz;
				}
				
				for (int i = t; i >= s; --i) {
					if ((res == B[t/Bsiz][i%Bsiz].first)) res = B[t/Bsiz][i%Bsiz].second;
					else if ((res == B[t/Bsiz][i%Bsiz].second)) res = B[t/Bsiz][i%Bsiz].first;
				}
			}
		} else {
			if (s / Bsiz == t / Bsiz) {
				for (int i = s; i <= t; ++i) {
					if ((res == B[s/Bsiz][i%Bsiz].first)) res = B[s/Bsiz][i%Bsiz].second;
					else if ((res == B[s/Bsiz][i%Bsiz].second)) res = B[s/Bsiz][i%Bsiz].first;
				}
			} else {
				while (true) {
					if ((res == B[s/Bsiz][s%Bsiz].first)) res = B[s/Bsiz][s%Bsiz].second;
					else if ((res == B[s/Bsiz][s%Bsiz].second)) res = B[s/Bsiz][s%Bsiz].first;
					++s;
					if (s % Bsiz == 0) break;
				}
				
				while (true) {
					if (s / Bsiz == t / Bsiz) break;
					if (pre[s/Bsiz].count(res)) res = pre[s/Bsiz][res];
					s += Bsiz;
				}
				
				for (int i = s; i <= t; ++i) {
					if ((res == B[s/Bsiz][i%Bsiz].first)) res = B[s/Bsiz][i%Bsiz].second;
					else if ((res == B[s/Bsiz][i%Bsiz].second)) res = B[s/Bsiz][i%Bsiz].first;
				}
			}
		}
		
		cout << res + 1 << '\n';
	}
}
accuracy: 1
time_ms: 1820
memory_kb: 20360
final_rank: 16

code_snippet: //#pragma GCC target ("avx2")
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _USE_MATH_DEFINES
#include<iostream>
#include<string>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<list>
#include<iomanip>
#include<vector>
#include<random>
#include<functional>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<unordered_map>
#include<climits>
#include<fstream>
#include<complex>
#include<time.h>
#include<cassert>
#include<functional>
#include<numeric>
#include<tuple>
using namespace std;
using ll = long long;
using ld = long double;
using H = pair<ll, ll>;
using P = pair<ll, H>;
using vi = vector<ll>;
#define all(a) (a).begin(),(a).end()
#define fs first
#define sc second
#define xx first
#define yy second.first
#define zz second.second
#define Q(i,j,k) mkp((i),mkp((j),(k)))
#define rng(i,s,n) for(ll i = (s) ; i < (n) ; i++)
#define rep(i,n) rng(i, 0, (n))
#define mkp make_pair
#define vec vector
#define pb emplace_back
#define siz(a) int((a).size())
#define crdcomp(b) sort(all((b)));(b).erase(unique(all((b))),(b).end())
#define getidx(b,i) (lower_bound(all((b)),(i))-(b).begin())
#define ssp(i,n) (i==(ll)(n)-1?"\n":" ")
#define ctoi(c) (int)((c)-'0')
#define itoc(c) (char)((c)+'0')
#define cyes printf("Yes\n")
#define cno printf("No\n")
#define cdf(n) for(int quetimes_=(n);quetimes_>0;quetimes_--)
#define gcj printf("Case #%lld: ",quetimes_+1)
#define readv(a,n) (a).resize((n),0);rep(i,(n)) (a)[i]=read()
#define found(a,x) (a.find(x)!=a.end())
constexpr ll mod = (ll)1e9 + 7;
constexpr ll Mod = 998244353;
constexpr ld EPS = 1e-10;
constexpr ll inf = (ll)3 * 1e18;
constexpr int Inf = (ll)15 * 1e8;
constexpr int dx[] = { -1,1,0,0 }, dy[] = { 0,0,-1,1 };
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
ll read() { ll u, k = scanf("%lld", &u); return u; }
string reads() { string s; cin >> s; return s; }
H readh(short g = 0) { H u; int k = scanf("%lld %lld", &u.fs, &u.sc); if (g == 1) u.fs--, u.sc--; if (g == 2) u.fs--; return u; }
bool ina(H t, int h, int w) { return 0 <= t.fs && t.fs < h && 0 <= t.sc && t.sc < w; }
bool ina(int t, int l, int r) { return l <= t && t < r; }
ll gcd(ll i, ll j) { return j ? gcd(j, i % j) : i; }
ll ppc(ll x) {
    int sum = 0; for (int i = 0; i < 60; i++)if ((1ll << i) & x) sum++;
    return sum;
}
template<typename T>
void fin(T x) { cout << x << endl; exit(0); }

template<typename T>
class csum {
    vec<T> v;
public:
    csum(vec<T>& a) :v(a) { build(); }
    csum() {}
    csum(int sz) { init(sz); }
    void init(int sz) { v = vector<T>(sz + 1, 0); }
    void init(vec<T>& a) { v = a; build(); }
    void build() {
        for (int i = 1; i < v.size(); i++) v[i] += v[i - 1];
    }
    void add(int l, int r, T x) {
        v[l] += x;
        v[r] -= x;
    }//[l,r)
    void add(int t, T x) {
        v[t] += x;
    }//[l,r)
    //[l,r]
    T a(int l, int r) {
        if (r < l) return 0;
        return v[r] - (l == 0 ? 0 : v[l - 1]);
    }
    //[l,r)
    T b(int l, int r) {
        return a(l, r - 1);
    }
    T a(pair<int, int>t) {
        return a(t.first, t.second);
    }
    T b(pair<int, int>t) {
        return b(t.first, t.second);
    }
    T operator[](int x)const {
        return v[x];
    }
};
class via {
    using H = pair<ll, ll>;
    bool comp;
public:
    vector<H>a;
    via() :comp(true) {}
    via(vector<H>dat) :a(dat), comp(false) { build(); }
    void push(int l, int r) { a.push_back(H{ l,r }); comp = false; }
    void push(H a) { push(a.first, a.second); }
    void build() {
        if (comp) return;
        comp = true;
        sort(a.begin(), a.end());
        int fst = -1; ll lst = -1;
        vector<H>b;
        for (int i = 0; i < a.size(); i++) {
            if (fst < 0) fst = i, lst = a[i].second;
            if (lst < a[i].first) {
                b.push_back(H{ a[fst].first,lst });
                fst = i, lst = a[i].second;
            }
            else if (lst < a[i].second) lst = a[i].second;
        }
        if (~fst) b.push_back(H{ a[fst].first, lst });
        a = b;
    }
    ll size() { return ll(a.size()); }
    ll sum() {
        build();
        ll sum = 0;
        for (auto g : a) sum += g.second - g.first;
        return sum;
    }
    via inter(via& v) {
        build(); v.build();
        via ret;
        for (auto g : a) ret.push(g);
        for (auto g : v.a) ret.push(g);
        ret.build(); return ret;
    }
    via comb(via& v) {
        build(); v.build();
        int s = 0, t = 0;
        via ret;
        while (s < a.size() && t < v.size()) {
            if (v[t].second <= a[s].first)  t++;
            else if (a[s].second <= v[t].first) s++;
            else {
                ret.push(max(a[s].first, v[t].first), min(a[s].second, v[t].second));
                if (a[s].second <= v[t].second) s++;
                else t++;
            }
        }
        return ret;
    }
    H& operator[](int t) { return a[t]; }
};
template<ll mod>
class modint {
public:ll v;
      modint(ll v = 0) { s(v % mod + mod); }
      constexpr static int fn_ = (ll)2e6 + 5;
      static vector<modint>fact, comp;
      modint pow(ll x) const {
          modint b(v), c(1);
          while (x) {
              if (x & 1) c *= b;
              b *= b;
              x >>= 1;
          }
          return c;
      }
      inline modint& s(int vv) {
          v = vv < mod ? vv : vv - mod;
          return *this;
      }
      inline modint inv()const { return pow(mod - 2); }
      inline modint operator-()const { return modint() - *this; }
      inline modint& operator+=(const modint b) { return s(v + b.v); }
      inline modint& operator-=(const modint b) { return s(v + mod - b.v); }
      inline modint& operator*=(const modint b) { v = v * b.v % mod; return *this; }
      inline modint& operator/=(const modint b) { v = v * b.inv().v % mod; return *this; }
      inline modint operator+(const modint& b) const { return modint(v) += b; }
      inline modint operator-(const modint& b) const { return modint(v) -= b; }
      inline modint operator*(const modint& b) const { return modint(v) *= b; }
      inline modint operator/(const modint& b) const { return modint(v) /= b; }
      friend ostream& operator<<(ostream& os, const modint& m) {
          return os << m.v;
      }
      friend istream& operator>>(istream& is, modint& m) {
          int x; is >> x; m = modint(x);
          return is;
      }
      bool operator<(const modint& r)const { return v < r.v; }
      bool operator>(const modint& r)const { return v > r.v; }
      bool operator<=(const modint& r)const { return v <= r.v; }
      bool operator>=(const modint& r)const { return v >= r.v; }
      bool operator==(const modint& r)const { return v == r.v; }
      bool operator!=(const modint& r)const { return v != r.v; }
      explicit operator bool()const { return v; }
      explicit operator int()const { return v; }
      modint comb(modint k) {
          if (k > *this) return modint();
          if (fact.empty()) combinit();
          if (v >= fn_) {
              if (k > *this - k) k = *this - k;
              modint tmp(1);
              for (int i = v; i >= v - k.v + 1; i--) tmp *= modint(i);
              return tmp * comp[k.v];
          }
          return fact[v] * comp[k.v] * comp[v - k.v];
      }//nCk
      modint perm(modint k) {
          if (k > *this) return modint();
          if (fact.empty()) combinit();
          if (v >= fn_) {
              modint tmp(1);
              for (int i = v; i >= v - k.v + 1; i--) tmp *= modint(i);
              return tmp;
          }
          return fact[v] * comp[v - k.v];
      }//nPk
      static void combinit() {
          fact.assign(fn_, modint());
          fact[0] = 1;
          for (int i = 1; i < fn_; i++) fact[i] = fact[i - 1] * modint(i);
          comp.assign(fn_, modint());
          comp[fn_ - 1] = fact[fn_ - 1].inv();
          for (int i = fn_ - 2; i >= 0; i--) comp[i] = comp[i + 1] * modint(i + 1);
      }
};
using mint = modint<ll(1e9 + 7)>; template<>vec<mint> mint::fact = vec<mint>(); template<>vec<mint> mint::comp = vec<mint>();
//--------------------------------------------------------------
//--------------------------------------------------------------

int n, k, q;
int rr;
//from, to
vec<vi>a, b;

void query(int i, int s, int t, int l, int r, int& x) {
    if (t <= l || r <= s) return;
    if (s <= l && r <= t) {
        int k = lower_bound(all(a[i]), x) - a[i].begin();
        if (k < siz(a[i]) && a[i][k] == x) x = b[i][k];
        return;
    }
    query(i * 2, s, t, l, (l + r) >> 1, x);
    query(i * 2 + 1, s, t, (l + r) >> 1, r, x);
}

signed main() {
    cin >> n >> k >> q;
    rr = 1; while(rr < k) rr <<= 1;
    a.resize(2 * rr); b.resize(2 * rr);
    rep(i, k) {
        int s, t; cin >> s >> t;
        if (s > t) swap(s, t);
        a[rr + i].pb(s); a[rr + i].pb(t);
        b[rr + i].pb(t); b[rr + i].pb(s);
    }

    for (int i = rr - 1; i >= 0; i--) {
        merge(all(a[i * 2]), all(a[i * 2 + 1]), back_inserter(a[i]));
        a[i].erase(unique(all(a[i])), a[i].end()); 
        b[i].erase(unique(all(b[i])), b[i].end());
        b[i] = a[i];
        rep(j, siz(a[i * 2])) {
            b[i][getidx(a[i], a[i * 2][j])] = b[i * 2][j];
        }
        rep(j, siz(a[i])) {
            int k = lower_bound(all(a[i * 2 + 1]), b[i][j]) - a[i * 2 + 1].begin();
            if (k < siz(a[i * 2 + 1]) && a[i * 2 + 1][k] == b[i][j]) {
                b[i][j] = b[i * 2 + 1][k];
            }
        }
    }

    struct st {
        int k, s, t, x;
    };
    vec<st>qry;
    vi ans(q);
    rep(i, q) {
        int c, s, t, x; cin >> c >> s >> t >> x;
        qry.pb(st{ c,s,t,x });
        s--;
        if (c == 2) {
            query(1, s, t, 0, rr, x);
            ans[i] = x;
        }
    }

    for (int i = 0; i < rr; i++) a[i].clear(), b[i].clear();
    rng(i, rr, rr + k / 2) {
        swap(a[i], a[(rr + k) - (i - rr) - 1]);
        swap(b[i], b[(rr + k) - (i - rr) - 1]);
    }
    for (int i = rr - 1; i >= 0; i--) {
        merge(all(a[i * 2]), all(a[i * 2 + 1]), back_inserter(a[i]));
        a[i].erase(unique(all(a[i])), a[i].end());
        b[i].erase(unique(all(b[i])), b[i].end());
        b[i] = a[i];
        rep(j, siz(a[i * 2])) {
            b[i][getidx(a[i], a[i * 2][j])] = b[i * 2][j];
        }
        rep(j, siz(a[i])) {
            int k = lower_bound(all(a[i * 2 + 1]), b[i][j]) - a[i * 2 + 1].begin();
            if (k < siz(a[i * 2 + 1]) && a[i * 2 + 1][k] == b[i][j]) {
                b[i][j] = b[i * 2 + 1][k];
            }
        }
    }

    rep(i, q) {
        int c, s, t, x; 
        c = qry[i].k;
        s = qry[i].s;
        t = qry[i].t;
        x = qry[i].x;
        if (c == 1) {
            query(1, k - t, k - s + 1, 0, rr, x);
            ans[i] = x;
        }
    }

    rep(i, q) cout << ans[i] << endl;
}
accuracy: 1
time_ms: 670
memory_kb: 81468
final_rank: 14

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);++i)
using namespace std;using ll=long long;
#define P push_back
#define C back
#define e second
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int N,K,Q;cin>>N>>K>>Q;vector<vector<pair<int,int>>>A(N),B(N);rep(i,N)A[i].P({0,i}),B[i].P({0,i});rep(i,K){int a,b;cin>>a>>b;a--;b--;B[A[a].C().e].P({i+1,b});B[A[b].C().e].P({i+1,a});int c=A[a].C().e,d=A[b].C().e;A[a].P({i+1,d});A[b].P({i+1,c});}while(Q--){int o,s,t,x;cin>>o>>s>>t>>x;x--;t++;auto i=prev(upper_bound(A[x].begin(),A[x].end(),make_pair(o==1?t:s,-1)));auto j=prev(upper_bound(B[i->e].begin(),B[i->e].end(),make_pair(o==1?s:t,-1)));cout<<j->e+1<<"\n";}}
accuracy: 1
time_ms: 70
memory_kb: 18316
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(n);++i)
using namespace std;
using ll = long long;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int N,K,Q;
    cin >> N >> K >> Q;

    vector<vector<pair<int,int>>> A(N);
    rep(i,N) A[i].push_back(make_pair(0,i));
    vector<vector<pair<int,int>>> B(N);
    rep(i,N) B[i].push_back(make_pair(0,i));

    rep(i,K){
        int a,b;
        cin >> a >> b;
        a--;b--;



        B[A[a].back().second].push_back(make_pair(i+1,b));
        B[A[b].back().second].push_back(make_pair(i+1,a));
        
        int c = A[a].back().second;
        int d = A[b].back().second;
        A[a].push_back(make_pair(i+1,d));
        A[b].push_back(make_pair(i+1,c));
    }

    rep(qi,Q){
        int o,s,t,x;
        cin >> o >> s >> t >> x;
        x--;t++;
        if(o==1){
            int r = prev(upper_bound(A[x].begin(),A[x].end(),make_pair(t,-1)))->second;
            int li = prev(upper_bound(B[r].begin(),B[r].end(),make_pair(s,-1)))->second;

            cout << li+1 << "\n";
        }
        else{
            int l = prev(upper_bound(A[x].begin(),A[x].end(),make_pair(s,-1)))->second;
            int ri = prev(upper_bound(B[l].begin(),B[l].end(),make_pair(t,-1)))->second;

            cout << ri+1 << "\n"; 
        }
    }

}
accuracy: 1
time_ms: 80
memory_kb: 18392
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define REP(i, n) for(int i = 0; i < (int)(n); ++i)
#define FOR(i, l, r) for(int i = (int)(l); i < (int)(r); ++i)
#define ALL(v) (v).begin(), (v).end()
using llong = long long;
using vi = std::vector<int>;
using vvi = std::vector<vi>;
using pii = std::pair<int, int>;
using namespace std;
constexpr int INF = 1e9;
constexpr long long LINF = 1e18;
constexpr double EPS = 1e-10;
constexpr int MOD = 998'244'353;
constexpr int MOD2 = 1e9 + 7;

template <typename Type>
inline std::istream &operator>>(std::istream &is, std::vector<Type> &v) {
    for(Type &in : v) is >> in;
    return is;
}

template <typename Type>
inline std::ostream &operator<<(std::ostream &os, const std::vector<Type> &v) {
    for(auto itr = v.cbegin(); itr != v.cend(); ++itr) os << (itr == v.cbegin() ? "" : " ") << *itr;
    return os;
}

#ifdef DEBUG

#include "lib/Utils/debug.hpp"
using namespace algorithm;

#else

#define debug(...) static_cast<void>(0)

#endif

// Mo's Algorithm（クエリ平方分割）.
class Mo {
    int m_len;                                          // m_len:=(区間の長さ).
    int m_q;                                            // m_q:=(クエリ数).
    std::vector<std::tuple<int, int, int> > m_queries;  // m_queries[i]:=(i番目の区間クエリ). tuple of (left, right, index).

    void sort_queries() {
        if(m_q == 0) return;
        const int width = std::max(m_len / (int)std::sqrt(m_q), 1);  // width:=N/√Q.
        std::sort(m_queries.begin(), m_queries.end(), [&width](const std::tuple<int, int, int> &a, const std::tuple<int, int, int> &b) -> bool {
            const auto &[al, ar, _] = a;
            const auto &[bl, br, __] = b;
            int a_block = al / width, b_block = bl / width;
            if(a_block == b_block) return (a_block & 1 ? ar > br : ar < br);
            return a_block < b_block;
        });
    }

public:
    Mo() : Mo(0) {}
    explicit Mo(size_t n) : m_len(n), m_q(0) {}
    explicit Mo(size_t n, size_t q) : Mo(n) {
        m_queries.reserve(q);
    }

    // 区間[l,r)についてのクエリを追加する．
    void insert(int l, int r) {
        assert(0 <= l and l < r and r <= m_len);
        m_queries.emplace_back(l, r, m_q++);
    }
    // 各クエリを実行する．O(Q*logQ+α*N*√Q).
    template <class F1, class F2, class F3>
    void execute(const F1 &add, const F2 &del, const F3 &solve) { execute(add, add, del, del, solve); }
    template <class F1, class F2, class F3, class F4, class F5>
    void execute(const F1 &add_l, const F2 &add_r, const F3 &del_l, const F4 &del_r, const F5 &solve) {
        sort_queries();
        int l = 0, r = 0;
        for(const auto &[nl, nr, idx] : m_queries) {
            while(nl < l) add_l(--l);
            while(r < nr) add_r(r++);
            while(l < nl) del_l(l++);
            while(nr < r) del_r(--r);
            solve(idx);
        }
    }
    void reset() {
        m_queries.clear();
        m_q = 0;
    }
};

int main() {
    int n;
    int k;
    int q;
    std::cin >> n >> k >> q;

    std::vector<std::pair<int, int> > vp(k);
    for(auto &[a, b] : vp) {
        std::cin >> a >> b;
        a--, b--;
    }

    std::vector<std::pair<int, int> > queries(q);
    Mo mo(k, q);
    for(int i = 0; i < q; ++i) {
        int type;
        int s, t;
        int x;
        std::cin >> type >> s >> t >> x;
        s--, x--;

        queries[i] = std::pair<int, int>(type, x);
        mo.insert(s, t);
    }

    std::vector<int> ans(q);
    std::vector<int> alpha(n), inv(n);
    std::iota(alpha.begin(), alpha.end(), 0);
    std::iota(inv.begin(), inv.end(), 0);
    auto swap_l = [&](int itr) -> void {
        const auto &[a, b] = vp[itr];
        std::swap(alpha[inv[a]], alpha[inv[b]]);
        std::swap(inv[a], inv[b]);
    };
    auto swap_r = [&](int itr) -> void {
        const auto &[a, b] = vp[itr];
        std::swap(inv[alpha[a]], inv[alpha[b]]);
        std::swap(alpha[a], alpha[b]);
    };
    auto solve = [&](int idx) -> void {
        const auto &[type, x] = queries[idx];
        ans[idx] = (type == 1 ? alpha[x] + 1 : inv[x] + 1);
    };
    mo.execute(swap_l, swap_r, swap_l, swap_r, solve);

    for(auto elem : ans) std::cout << elem << "\n";
}
accuracy: 1
time_ms: 220
memory_kb: 7068
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#define REP(i,n)   for(int i=0;i<(int)(n);++i)
#define FOR(i,l,r) for(int i=(int)(l);i<(int)(r);++i)
#define ALL(v)     (v).begin(),(v).end()
using llong = long long;
using vi    = std::vector<int>;
using vvi   = std::vector<vi>;
using pii   = std::pair<int,int>;
using namespace std;
constexpr int       INF  = 1e9;
constexpr long long LINF = 1e18;
constexpr double    EPS  = 1e-10;
constexpr int       MOD  = 998'244'353;
constexpr int       MOD2 = 1e9+7;

template <typename Type>
inline std::istream &operator>>(std::istream &is, std::vector<Type> &v) {
    for(Type &in : v) is >> in;
    return is;
}

template <typename Type>
inline std::ostream &operator<<(std::ostream &os, const std::vector<Type> &v) {
    for(auto itr = v.cbegin(); itr != v.cend(); ++itr) os << (itr == v.cbegin() ? "" : " ") << *itr;
    return os;
}

#ifdef DEBUG

#include "src/Utils/debug.hpp"
using namespace algorithm;

#else

#define debug(...) static_cast<void>(0)

#endif

// Mo's Algorithm（クエリ平方分割）.
class Mo {
    int m_len;                                          // m_len:=(区間の長さ).
    int m_q;                                            // m_q:=(クエリ数).
    std::vector<std::tuple<int, int, int> > m_queries;  // m_queries[i]:=(i番目の区間クエリ). tuple of (left, right, index).

    void sort_query() {
        const int width = std::sqrt(m_len);
        auto comp = [&width](const std::tuple<int, int, int> &a, const std::tuple<int, int, int> &b) -> bool {
            const auto &[al, ar, _] = a;
            const auto &[bl, br, __] = b;
            int a_block = al / width, b_block = bl / width;
            if(a_block == b_block) return (a_block & 1 ? ar > br : ar < br);
            return a_block < b_block;
        };
        std::sort(m_queries.begin(), m_queries.end(), comp);
    }

public:
    Mo() : Mo(0) {}
    explicit Mo(size_t n) : m_len(n), m_q(0) {}
    explicit Mo(size_t n, size_t q) : Mo(n) {
        m_queries.reserve(q);
    }

    // 区間[l,r)についてのクエリを追加する．
    void insert(int l, int r) {
        assert(0 <= l and l < r and r <= m_len);
        m_queries.emplace_back(l, r, m_q++);
    }
    // 各クエリを実行する．O(α(N+Q)√N).
    template <class F1, class F2, class F3>
    void execute(const F1 &add, const F2 &del, const F3 &solve) { execute(add, del, add, del, solve); }
    template <class F1, class F2, class F3, class F4, class F5>
    void execute(const F1 &add_l, const F2 &del_l, const F3 &add_r, const F4 &del_r, const F5 &solve) {
        sort_query();
        int l = 0, r = 0;
        for(const auto &[nl, nr, idx] : m_queries) {
            while(nl < l) add_l(--l);
            while(r < nr) add_r(r++);
            while(l < nl) del_l(l++);
            while(nr < r) del_r(--r);
            solve(idx);
        }
    }
    void reset() {
        m_queries.clear();
        m_q = 0;
    }
};

int main(){
    int n;
    int k;
    int q;
    cin>>n>>k>>q;

    vector<pii> vp(k);
    for(auto &[a,b]:vp){
        cin>>a>>b;
        a--, b--;
    }

    vector<pii> queries(q);
    Mo mo(k,q);
    REP(i,q){
        int type;
        int s,t;
        int x;
        cin>>type>>s>>t>>x;
        s--, x--;

        queries[i]=pii(type,x);
        mo.insert(s,t);
    }

    vi ans(q);
    vi alpha(n), inv(n);
    iota(ALL(alpha),0);
    iota(ALL(inv),0);
    auto swap_l=[&](int itr)->void{
        const auto &[a,b]=vp[itr];
        swap(alpha[inv[a]],alpha[inv[b]]);
        swap(inv[a],inv[b]);
    };
    auto swap_r=[&](int itr)->void{
        const auto &[a,b]=vp[itr];
        swap(inv[alpha[a]],inv[alpha[b]]);
        swap(alpha[a],alpha[b]);
    };
    auto solve=[&](int idx)->void{
        const auto &[type,x]=queries[idx];
        ans[idx]=(type==1?alpha[x]+1:inv[x]+1);
    };
    mo.execute(swap_l,swap_l,swap_r,swap_r,solve);

    for(auto out:ans) cout<<out<<"\n";
}
accuracy: 1
time_ms: 220
memory_kb: 7076
final_rank: 10

code_snippet: #include <bits/stdc++.h>
#define REP(i,n)   for(int i=0;i<(int)(n);++i)
#define FOR(i,l,r) for(int i=(int)(l);i<(int)(r);++i)
#define ALL(v)     (v).begin(),(v).end()
using llong = long long;
using vi    = std::vector<int>;
using vvi   = std::vector<vi>;
using pii   = std::pair<int,int>;
using namespace std;
constexpr int       INF  = 1e9;
constexpr long long LINF = 1e18;
constexpr double    EPS  = 1e-10;
constexpr int       MOD  = 998'244'353;
constexpr int       MOD2 = 1e9+7;

template <typename Type>
inline std::istream &operator>>(std::istream &is, std::vector<Type> &v) {
    for(Type &in : v) is >> in;
    return is;
}

template <typename Type>
inline std::ostream &operator<<(std::ostream &os, const std::vector<Type> &v) {
    for(auto itr = v.cbegin(); itr != v.cend(); ++itr) os << (itr == v.cbegin() ? "" : " ") << *itr;
    return os;
}

#ifdef DEBUG

#include "src/Utils/debug.hpp"
using namespace algorithm;

#else

#define debug(...) static_cast<void>(0)

#endif

// Mo's Algorithm（クエリ平方分割）.
class Mo {
    int m_len;                                          // m_len:=(区間の長さ).
    int m_q;                                            // m_q:=(クエリ数).
    std::vector<std::tuple<int, int, int> > m_queries;  // m_queries[i]:=(i番目の区間クエリ). tuple of (left, right, index).

    void sort_query() {
        const int width = std::sqrt(m_len);
        auto comp = [&width](const std::tuple<int, int, int> &a, const std::tuple<int, int, int> &b) -> bool {
            const auto &[al, ar, _] = a;
            const auto &[bl, br, __] = b;
            int a_block = al / width, b_block = bl / width;
            if(a_block == b_block) return (a_block & 1 ? ar > br : ar < br);
            return a_block < b_block;
        };
        std::sort(m_queries.begin(), m_queries.end(), comp);
    }

public:
    Mo() : Mo(0) {}
    explicit Mo(size_t n) : m_len(n), m_q(0) {}
    explicit Mo(size_t n, size_t q) : Mo(n) {
        m_queries.reserve(q);
    }

    // 区間[l,r)についてのクエリを追加する．
    void insert(int l, int r) {
        assert(0 <= l and l < r and r <= m_len);
        m_queries.emplace_back(l, r, m_q++);
    }
    // 各クエリを実行する．O(α(N+Q)√N).
    template <class F1, class F2, class F3>
    void execute(const F1 &add, const F2 &del, const F3 &solve) { execute(add, del, add, del, solve); }
    template <class F1, class F2, class F3, class F4, class F5>
    void execute(const F1 &add_l, const F2 &del_l, const F3 &add_r, const F4 &del_r, const F5 &solve) {
        sort_query();
        int l = 0, r = 0;
        for(const auto &[nl, nr, idx] : m_queries) {
            while(nl < l) add_l(--l);
            while(r < nr) add_r(r++);
            while(l < nl) del_l(l++);
            while(nr < r) del_r(--r);
            solve(idx);
        }
    }
    void reset() {
        m_queries.clear();
        m_q = 0;
    }
};

int main(){
    int n;
    int k;
    int q;
    cin>>n>>k>>q;

    vector<pii> vp(k);
    for(auto &[a,b]:vp){
        cin>>a>>b;
        a--, b--;
    }

    vector<pii> queries(q);
    Mo mo(n,q);
    REP(i,q){
        int type;
        int s,t;
        int x;
        cin>>type>>s>>t>>x;
        s--, x--;

        queries[i]=pii(type,x);
        mo.insert(s,t);
    }

    vi ans(q);
    vi alpha(n), inv(n);
    iota(ALL(alpha),0);
    iota(ALL(inv),0);
    auto swap_l=[&](int itr)->void{
        const auto &[a,b]=vp[itr];
        swap(alpha[inv[a]],alpha[inv[b]]);
        swap(inv[a],inv[b]);
    };
    auto swap_r=[&](int itr)->void{
        const auto &[a,b]=vp[itr];
        swap(inv[alpha[a]],inv[alpha[b]]);
        swap(alpha[a],alpha[b]);
    };
    auto solve=[&](int idx)->void{
        const auto &[type,x]=queries[idx];
        ans[idx]=(type==1?alpha[x]+1:inv[x]+1);
    };
    mo.execute(swap_l,swap_l,swap_r,swap_r,solve);

    for(auto out:ans) cout<<out<<"\n";
}
accuracy: 0.2857142857142857
time_ms: 210
memory_kb: 6992
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
  // 入力を受け取る
  int N, K, Q;
  cin >> N >> K >> Q;
  vector<int> a(K), b(K);
  for( int i = 0; i < K; i++ ) {
    cin >> a[i] >> b[i];
    a[i]--, b[i]--;
  }
  vector<int> c(Q), s(Q), t(Q), x(Q);
  for( int i = 0; i < Q; i++ ) {
    cin >> c[i] >> s[i] >> t[i] >> x[i];
    c[i]--, s[i]--, t[i]--, x[i]--;
  }
  // ブロックごとに swap を圧縮
  constexpr int B = 500;
  const int L = (K+B-1)/B;
  vector p(L, vector<int>(N));
  vector q(L, vector<int>(N));
  for( int i = 0; i < L; i++ ) {
    iota(p[i].begin(), p[i].end(), 0);
  }
  for( int i = 0; i < K; i++ ) {
    swap(p[i/B][a[i]], p[i/B][b[i]]);
  }
  for( int i = 0; i < L; i++ ) {
    for( int j = 0; j < N; j++ ) {
      q[i][p[i][j]] = j;
    }
  }
  // クエリを処理する
  for( int i = 0; i < Q; i++ ) {
    if( c[i] == 0 ) {
      // 方針: 末尾から走査して、x の位置を管理する
      int op_id = t[i], pos_x = x[i];
      while( op_id >= s[i] ) {
        if( op_id%B == B-1 && op_id-B > s[i] ) {
          pos_x = p[op_id/B][pos_x];
          op_id -= B;
        }else {
          if( pos_x == a[op_id] || pos_x == b[op_id] ) {
            pos_x = pos_x^a[op_id]^b[op_id];
          }
          op_id -= 1;
        }
      }
      cout << pos_x + 1 << "\n";
    }else {
      // 方針: 先頭から走査して、x の位置を管理する
      int op_id = s[i], pos_x = x[i];
      while( op_id <= t[i] ) {
        if( op_id%B == 0 && op_id+B < t[i] ) {
          pos_x = q[op_id/B][pos_x];
          op_id += B;
        }else {
          if( pos_x == a[op_id] || pos_x == b[op_id] ) {
            pos_x = pos_x^a[op_id]^b[op_id];
          }
          op_id += 1;
        }
      }
      cout << pos_x + 1 << "\n";
    }
  }
}
accuracy: 1
time_ms: 1410
memory_kb: 162380
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
  // 入力を受け取る
  int N, K, Q;
  cin >> N >> K >> Q;
  vector<int> a(K), b(K);
  for( int i = 0; i < K; i++ ) {
    cin >> a[i] >> b[i];
    a[i]--, b[i]--;
  }
  vector<int> c(Q), s(Q), t(Q), x(Q);
  for( int i = 0; i < Q; i++ ) {
    cin >> c[i] >> s[i] >> t[i] >> x[i];
    c[i]--, s[i]--, t[i]--, x[i]--;
  }
  // ブロックごとに swap を圧縮
  const int B = 500;
  const int L = (K+B-1)/B;
  vector p(L, vector<int>(N));
  vector q(L, vector<int>(N));
  for( int i = 0; i < L; i++ ) {
    iota(p[i].begin(), p[i].end(), 0);
  }
  for( int i = 0; i < K; i++ ) {
    swap(p[i/B][a[i]], p[i/B][b[i]]);
  }
  for( int i = 0; i < L; i++ ) {
    for( int j = 0; j < N; j++ ) {
      q[i][p[i][j]] = j;
    }
  }
  // クエリを処理する
  for( int i = 0; i < Q; i++ ) {
    if( c[i] == 0 ) {
      // 方針: 末尾から走査して、x の位置を管理する
      int op_id = t[i], pos_x = x[i];
      while( op_id >= s[i] ) {
        if( op_id%B == B-1 && op_id-B >= s[i] ) {
          pos_x = p[op_id/B][pos_x];
          op_id -= B;
        }else {
          if( pos_x == a[op_id] || pos_x == b[op_id] ) {
            pos_x = pos_x^a[op_id]^b[op_id];
          }
          op_id -= 1;
        }
      }
      cout << pos_x + 1 << "\n";
    }else {
      // 方針: 先頭から走査して、x の位置を管理する
      int op_id = s[i], pos_x = x[i];
      while( op_id <= t[i] ) {
        if( op_id%B == 0 && op_id+B <= t[i] ) {
          pos_x = q[op_id/B][pos_x];
          op_id += B;
        }else {
          if( pos_x == a[op_id] || pos_x == b[op_id] ) {
            pos_x = pos_x^a[op_id]^b[op_id];
          }
          op_id += 1;
        }
      }
      cout << pos_x + 1 << "\n";
    }
  }
}
accuracy: 1
time_ms: 1400
memory_kb: 162380
final_rank: 17

code_snippet: #include <bits/stdc++.h>

int main() {
    int n, k, q;
    std::cin >> n >> k >> q;
    std::vector split(n, std::vector<int>(1, -1));
    std::vector<std::pair<int, int>> ope;
    for (int i = 0; i < k; i++) {
        int a, b;
        std::cin >> a >> b;
        a--; b--;
        split[a].push_back(i);
        split[b].push_back(i);
        ope.emplace_back(a, b);
    }
    for (int i = 0; i < n; i++) split[i].push_back(k);

    auto f = [&](auto self, int cur_time, const int fin_time, int pos) -> int {
        assert(cur_time <= fin_time);
        if (cur_time == fin_time) return pos;
        auto it = std::lower_bound(split[pos].begin(), split[pos].end(), cur_time);
        assert(it != split[pos].end());
        int next_ope_time = *it;
        if (next_ope_time < fin_time) {
            auto [a, b] = ope[next_ope_time];
            return self(self, next_ope_time + 1, fin_time, a ^ b ^ pos);
        } else {
            return pos;
        }
    };

    auto g = [&](auto self, int cur_time, const int fin_time, int pos) -> int {
        assert(cur_time >= fin_time);
        if (cur_time == fin_time) return pos;
        auto it = std::lower_bound(split[pos].begin(), split[pos].end(), cur_time);
        assert(it != split[pos].begin());
        it--;
        int next_ope_time = *it;
        if (next_ope_time >= fin_time) {
            auto [a, b] = ope[next_ope_time];
            return self(self, next_ope_time, fin_time, a ^ b ^ pos);
        } else {
            return pos;
        }
    };

    while (q--) {
        int t;
        std::cin >> t;
        if (t == 1) {
            int l, r, x;
            std::cin >> l >> r >> x;
            l--; x--;
            std::cout << g(g, r, l, x) + 1 << '\n';
        } else {
            int l, r, x;
            std::cin >> l >> r >> x;
            l--; x--;
            std::cout << f(f, l, r, x) + 1 << '\n';
        }
    }
}
accuracy: 1
time_ms: 170
memory_kb: 10468
final_rank: 7

code_snippet: #include <bits/stdc++.h>

int main() {
    int n, k, q;
    std::cin >> n >> k >> q;
    std::vector split(n, std::vector<int>(1, -1));
    std::vector<std::pair<int, int>> ope;
    for (int i = 0; i < k; i++) {
        int a, b;
        std::cin >> a >> b;
        a--; b--;
        split[a].push_back(i);
        split[b].push_back(i);
        ope.emplace_back(a, b);
    }
    for (int i = 0; i < n; i++) split[i].push_back(n);

    auto f = [&](auto self, int cur_time, const int fin_time, int pos) -> int {
        assert(cur_time <= fin_time);
        if (cur_time == fin_time) return pos;
        auto it = std::lower_bound(split[pos].begin(), split[pos].end(), cur_time);
        assert(it != split[pos].end());
        int next_ope_time = *it;
        if (next_ope_time < fin_time) {
            auto [a, b] = ope[next_ope_time];
            return self(self, next_ope_time + 1, fin_time, a ^ b ^ pos);
        } else {
            return pos;
        }
    };

    auto g = [&](auto self, int cur_time, const int fin_time, int pos) -> int {
        assert(cur_time >= fin_time);
        if (cur_time == fin_time) return pos;
        auto it = std::lower_bound(split[pos].begin(), split[pos].end(), cur_time);
        assert(it != split[pos].begin());
        it--;
        int next_ope_time = *it;
        if (next_ope_time >= fin_time) {
            auto [a, b] = ope[next_ope_time];
            return self(self, next_ope_time, fin_time, a ^ b ^ pos);
        } else {
            return pos;
        }
    };

    while (q--) {
        int t;
        std::cin >> t;
        if (t == 1) {
            int l, r, x;
            std::cin >> l >> r >> x;
            l--; x--;
            std::cout << g(g, r, l, x) + 1 << '\n';
        } else {
            int l, r, x;
            std::cin >> l >> r >> x;
            l--; x--;
            std::cout << f(f, l, r, x) + 1 << '\n';
        }
    }
}
accuracy: 0.2857142857142857
time_ms: 170
memory_kb: 10368
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define overload(a,b,c,d,...) d
#define rep1(a) for(ll _=0;_<(ll)a;++_)
#define rep2(i,n) for(ll i=0;i<(ll)n;++i)
#define rep3(i,l,r) for(ll i=(ll)l;i<(ll)r;++i)
#define rep(...) overload(__VA_ARGS__,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(i,a) for(ll i=(ll)a-1;i>=0;--i)
#define rrep2(i,a,b) for(ll i=(ll)b-1;i>=(ll)a;--i)
#define rrep(...) overload(__VA_ARGS__,rrep2,rrep1)(__VA_ARGS__)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define pb push_back
#define eb emplace_back
using namespace std;
using ll=int;
using ull=unsigned long long;
using ld=long double;
template<typename T,typename U>inline bool chmin(T&a,const U&b){return (a>b?a=b,true:false);}
template<typename T,typename U>inline bool chmax(T&a,const U&b){return (a<b?a=b,true:false);}
static constexpr ll mod1=998244353;
static constexpr ll mod2=1000000007;
const ll base1=random_device()()%mod1;
const ll base2=random_device()()%mod2;
struct Mo{
	int n;
	vector<int>left,right;
	Mo(int n):n(n){}
	void add(int l,int r){
		left.pb(l);right.pb(r);
	}
	template<typename AL,typename AR,typename DL,typename DR,typename REM>
	void run(const AL&add_left,const AR&add_right,const DL&delete_left,const DR&delete_right,const REM&rem){
		const int q=left.size(),width=max<int>(1,int(sqrt(3)*n/sqrt(max(1,2*q))));
		vector<int>order(q);iota(all(order),0);
		sort(all(order),[&](int a,int b){
			const int ablock=left[a]/width,bblock=left[b]/width;
			if(ablock!=bblock)return ablock<bblock;
			return (ablock&1)?(right[a]>right[b]):(right[a]<right[b]);
		});
		int l=0,r=0;
		for(auto idx:order){
			while(l>left[idx])add_left(--l);
			while(r<right[idx])add_right(r++);
			while(l<left[idx])delete_left(l++);
			while(r>right[idx])delete_right(--r);
			rem(idx);
		}
	}
};
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	ll n,k,q;cin>>n>>k>>q;
	vector<pair<int,int>>s(k);
	for(auto&[l,r]:s){
		cin>>l>>r;
		l--,r--;
	}
	vector<int>idx(n),rev(n);
	iota(all(idx),0),iota(all(rev),0);
	vector<pair<int,int>>query(q);
	vector<int>ans(q);
	Mo mo(k);
	rep(i,q){
		ll tmp;cin>>tmp;
		ll s,t,x;cin>>s>>t>>x;
		s--,x--;
		query[i]={tmp,x};
		mo.add(s,t);
	}
	auto left=[&](int id)->void {
		const int x=rev[s[id].first],y=rev[s[id].second];
		swap(idx[x],idx[y]);
		swap(rev[s[id].first],rev[s[id].second]);
	};
	auto right=[&](int id)->void {
		int x=idx[s[id].first],y=idx[s[id].second];
		swap(idx[s[id].first],idx[s[id].second]);
		swap(rev[x],rev[y]);
	};
	auto rem=[&](int id)->void {
		//cerr<<id<<endl;
		//for(auto e:idx)cerr<<e<<" ";
		//cerr<<endl;
		//for(auto e:rev)cerr<<e<<" ";
		//cerr<<endl;
		ans[id]=(query[id].first==1?idx:rev)[query[id].second]+1;
	};
	mo.run(left,right,left,right,rem);
	for(auto&e:ans)cout<<e<<endl;
}
accuracy: 1
time_ms: 200
memory_kb: 7248
final_rank: 6

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 0425.cc: Chemical Substance Alpha
 */

#include<cstdio>
#include<vector>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 100000;
const int MAX_K = 100000;
const int MAX_QN = 100000;

/* typedef */

typedef vector<int> vi;

struct Query {
  int op, s, t, x;
  Query() {}
  Query(int _op, int _s, int _t, int _x): op(_op), s(_s), t(_t), x(_x) {}

  void read() { scanf("%d%d%d%d", &op, &s, &t, &x), s--, t--, x--; }
};

/* global variables */

int as[MAX_K], bs[MAX_K];
Query qs[MAX_QN];
vi sv1[MAX_K], tv1[MAX_K], sv2[MAX_K], tv2[MAX_K];
int ps[MAX_N], invps[MAX_N], ans[MAX_QN];

/* subroutines */

/* main */

int main() {
  int n, k, qn;
  scanf("%d%d%d", &n, &k, &qn);

  for (int i = 0; i < k; i++)
    scanf("%d%d", as + i, bs + i), as[i]--, bs[i]--;

  for (int i = 0; i < qn; i++) {
    qs[i].read();
    int si = qs[i].s, ti = qs[i].t;
    if (qs[i].op == 1)
      sv1[si].push_back(i), tv1[ti].push_back(i);
    else
      sv2[si].push_back(i), tv2[ti].push_back(i);
  }

  fill(ans, ans + qn, -1);
  for (int i = 0; i < n; i++) ps[i] = invps[i] = i;
  
  for (int i = 0; i < k; i++) {
    for (auto u: sv2[i]) ans[u] = ps[qs[u].x];

    int ai = as[i], bi = bs[i];
    swap(ps[ai], ps[bi]);
    swap(invps[ps[ai]], invps[ps[bi]]);

    for (auto u: tv1[i]) ans[u] = ps[qs[u].x];
    for (auto u: tv2[i]) ans[u] = invps[ans[u]];
  }

  for (int i = 0; i < n; i++) ps[i] = invps[i] = i;
  
  for (int i = 0; i < k; i++) {
    for (auto u: sv1[i]) ans[u] = invps[ans[u]];

    int ai = as[i], bi = bs[i];
    swap(ps[ai], ps[bi]);
    swap(invps[ps[ai]], invps[ps[bi]]);
  }

  for (int i = 0; i < qn; i++) printf("%d\n", ans[i] + 1);
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 20692
final_rank: 4

code_snippet: #ifdef LOGX
#define _GLIBCXX_DEBUG
#endif
#include<bits/stdc++.h>
using namespace std;

using ll=long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep2(i,s,n) for(int i=int(s);i<int(n);i++)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
const int big=1e9+7;
//const int big=998244353;
const char newl='\n';
const int inf=1e9+10;
const ll INF=ll(1e18)+10;
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};

struct info{
    int com;
    int s;
    int t;
    int x;
};

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    
    int n,k,q;
    cin >> n >> k >> q;
    vector<int> id(n),invid(n);
    iota(all(id),0);
    iota(all(invid),0);

    vector<int> a(k),b(k);
    rep(i,k)cin >> a[i] >> b[i],a[i]--,b[i]--;
    vector<info> query(q);
    rep(i,q){
        int com,s,t,x;
        cin >> com >> s >> t >> x;
        s--,t--,x--;
        query[i]={com,s,t,x};
    }
    vector<int> ans(q);

    //2番のクエリ処理
    {
        vector<int> v(q);
        vector<vector<int>> beg_query(k),en_query(k);
        rep(i,q){
            if(query[i].com==2){
                beg_query[query[i].s].emplace_back(i);
                en_query[query[i].t].emplace_back(i);
            }
        }
        rep(st,k){
            for(int i:beg_query[st]){
                v[i]=id[query[i].x];
            }
            swap(id[a[st]],id[b[st]]);
            swap(invid[id[a[st]]],invid[id[b[st]]]);
            for(int i:en_query[st]){
                ans[i]=invid[v[i]];
            }
        }
    }
    //1番のクエリ処理
    {
        vector<int> v(q);
        vector<vector<int>> beg_query(k),en_query(k);
        rep(i,q){
            if(query[i].com==1){
                beg_query[query[i].t].emplace_back(i);
                en_query[query[i].s].emplace_back(i);
            }
        }
        for(int st=k-1;st>=0;st--){
            for(int i:beg_query[st]){
                v[i]=id[query[i].x];
            }
            swap(id[a[st]],id[b[st]]);
            swap(invid[id[a[st]]],invid[id[b[st]]]);
            for(int i:en_query[st]){
                ans[i]=invid[v[i]];
            }
        }
    }
    rep(i,q)cout << ans[i]+1 << newl;
}
accuracy: 1
time_ms: 40
memory_kb: 14164
final_rank: 1

code_snippet: #include <bits/stdc++.h>

using ll = long long;

template <class T> using Vec = std::vector<T>;

constexpr int BUCKET = 330;

int main() {
    int N, K, Q;
    std::cin >> N >> K >> Q;
    Vec<int> A(K), B(K);
    for (int i = 0; i < K; ++i) {
        std::cin >> A[i] >> B[i];
        A[i] -= 1;
        B[i] -= 1;
    }
    Vec<int> T(Q), L(Q), R(Q), X(Q);
    Vec<Vec<int>> query((K + BUCKET - 1) / BUCKET);
    for (int i = 0; i < Q; ++i) {
        std::cin >> T[i] >> L[i] >> R[i] >> X[i];
        L[i] -= 1;
        X[i] -= 1;
        query[L[i] / BUCKET].push_back(i);
    }
    Vec<int> ans(Q);
    for (int q = 0; q < (int)query.size(); ++q) {
        auto& vec = query[q];
        std::sort(vec.begin(), vec.end(), [&](const int i, const int j) { return R[i] < R[j]; });
        Vec<int> perm(N), inv(N);
        std::iota(perm.begin(), perm.end(), 0);
        std::iota(inv.begin(), inv.end(), 0);
        int l = q * BUCKET, r = q * BUCKET;
        for (const int i : vec) {
            while (r < R[i]) {
                const int x = perm[A[r]], y = perm[B[r]];
                std::swap(perm[A[r]], perm[B[r]]);
                std::swap(inv[x], inv[y]);
                r += 1;
            }
            while (l < L[i]) {
                const int x = inv[A[l]], y = inv[B[l]];
                std::swap(perm[x], perm[y]);
                std::swap(inv[A[l]], inv[B[l]]);
                l += 1;
            }
            while (l > L[i]) {
                l -= 1;
                const int x = inv[A[l]], y = inv[B[l]];
                std::swap(perm[x], perm[y]);
                std::swap(inv[A[l]], inv[B[l]]);
            }
            ans[i] = (T[i] == 1 ? perm : inv)[X[i]] + 1;
        }
    }
    for (const int x : ans) {
        std::cout << x << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 7344
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;
template<class T> using vvvc = vc<vvc<T>>;
template<class T> using vvvvc = vvc<vvc<T>>;
template<class T> using PQ = priority_queue<T>;
template<class T> using invPQ = priority_queue<T, vector<T>, greater<T>>;
using IP = pair<int, int>;
using LP = pair<ll, ll>;
#define all(x) begin(x), end(x)
#define allr(x) rbegin(x), rend(x)
#define rep(i, n) for (int i = 0; (i) < (int)(n); i++)
#define rep3(i, m, n) for (int i = (m); (i) < (int)(n); i++)
#define repr(i, n) for (int i = (n) - 1; (i) >= 0; i--)
#define rep3r(i, m, n) for (int i = (n) - 1; (i) >= (int)(m); i--)
template<class T> inline bool chmax(T & a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T & a, T b) { if (a > b) { a = b; return 1; } return 0; }

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int N, K, Q;
    cin >> N >> K >> Q;
    vc<int> a(K), b(K), q(Q), s(Q), t(Q), x(Q);
    rep (i, K) {
        cin >> a[i] >> b[i];
        a[i]--; b[i]--;
    }
    rep (i, Q) {
        cin >> q[i] >> s[i] >> t[i] >> x[i];
        s[i]--; t[i]--; x[i]--;
    }
    
    int bsize = sqrt(K), bcnt = (K-1) / bsize + 1;
    vc<unordered_map<int, int>> backet(bcnt);
    rep (i, K) {
        int id = i / bsize;
        if (!backet[id].count(a[i])) backet[id][a[i]] = a[i];
        if (!backet[id].count(b[i])) backet[id][b[i]] = b[i];
        swap(backet[id][a[i]], backet[id][b[i]]);
    }
    vc<unordered_map<int, int>> rbacket(bcnt);
    rep (i, bcnt) {
        for (auto& p : backet[i]) {
            rbacket[i][p.second] = p.first;
        }
    }

    rep (i, Q) {
        if (q[i] == 1) {
            int p = x[i];
            int j = t[i];
            while ((j+1) % bsize != 0 && j >= s[i]) {
                if (a[j] == p) p = b[j];
                else if (b[j] == p) p = a[j];
                j--;
            }
            while (j - bsize + 1 >= s[i]) {
                if (backet[j / bsize].count(p)) p = backet[j / bsize][p];
                j -= bsize;
            }
            while (j >= s[i]) {
                if (a[j] == p) p = b[j];
                else if (b[j] == p) p = a[j];
                j--;
            }
            cout << p+1 << endl;
        }
        else {
            int p = x[i];
            int j = s[i];
            while (j % bsize != 0 && j <= t[i]) {
                if (a[j] == p) p = b[j];
                else if (b[j] == p) p = a[j];
                j++;
            }
            while (j + bsize - 1 <= t[i]) {
                if (rbacket[j / bsize].count(p)) p = rbacket[j / bsize][p];
                j += bsize;
            }
            while (j <= t[i]) {
                if (a[j] == p) p = b[j];
                else if (b[j] == p) p = a[j];
                j++;
            }
            cout << p+1 << endl;
        }
    }
}
accuracy: 1
time_ms: 1750
memory_kb: 21560
final_rank: 15

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int N,K,Q;
int ans[1<<17],a[1<<17],b[1<<17];
int num[1<<17],pos[1<<17];
vector<pair<int,int> >G[1<<17],H[1<<17];
int ord[1<<17],inv[1<<17];
main()
{
	cin>>N>>K>>Q;
	for(int i=0;i<K;i++)
	{
		cin>>a[i]>>b[i];
		a[i]--,b[i]--;
	}
	for(int i=0;i<Q;i++)
	{
		int q,s,t,x;cin>>q>>s>>t>>x;
		s--,t--,x--;
		if(q==1)
		{
			pos[i]=s;
			G[t+1].push_back(make_pair(i,x));
		}
		else
		{
			pos[i]=t+1;
			G[s].push_back(make_pair(i,x));
		}
	}
	for(int i=0;i<N;i++)ord[i]=i;
	for(int i=0;i<=K;i++)
	{
		for(pair<int,int>p:G[i])
		{
			num[p.first]=ord[p.second];
		}
		if(i<K)swap(ord[a[i]],ord[b[i]]);
	}
	for(int i=0;i<Q;i++)
	{
		H[pos[i]].push_back(make_pair(i,num[i]));
	}
	for(int i=0;i<N;i++)ord[i]=inv[i]=i;
	for(int i=0;i<=K;i++)
	{
		for(pair<int,int>p:H[i])
		{
			ans[p.first]=inv[p.second];
		}
		if(i<K)
		{
			inv[ord[a[i]]]=b[i];
			inv[ord[b[i]]]=a[i];
			swap(ord[a[i]],ord[b[i]]);
		}
	}
	for(int i=0;i<Q;i++)cout<<ans[i]+1<<endl;
}
accuracy: 1
time_ms: 210
memory_kb: 16240
final_rank: 12

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max() / 32 * 15 + 208;

const int B = 400;

struct Query {
    int l, r, no;
    Query(int l, int r, int no) : l(l), r(r), no(no) {}
    Query() : l(0), r(0), no(0) {}
    bool operator<(const Query &a) const {
        int ablock = this->l / B, bblock = a.l / B;
        if(ablock != bblock) return ablock < bblock;
        if(ablock & 1) return this->r < a.r;
        else return this->r > a.r;
    }
};


template <class T>
ostream& operator<<(ostream& os, vector<T> v) {
    os << "{";
    for (int i = 0; i < v.size(); ++i) {
        if(i) os << ", ";
        os << v[i];
    }
    return os << "}";
}

template <class L, class R>
ostream& operator<<(ostream& os, pair<L, R> p) {
    return os << "{" << p.first << ", " << p.second << "}";
}


int main() {
    int n, k, q;
    cin >> n >> k >> q;
    vector<int> a(k), b(k), x(n), y(n);
    for (int i = 0; i < k; ++i) {
        scanf("%d %d", &a[i], &b[i]);
        a[i]--; b[i]--;
    }
    vector<int> ans(q), t(q), val(q);
    iota(x.begin(),x.end(), 0);
    iota(y.begin(),y.end(), 0);
    vector<Query> query(q);
    for (int i = 0; i < q; ++i) {
        cin >> t[i] >> query[i].l >> query[i].r >> val[i];
        query[i].l--; val[i]--;
        query[i].no = i;
    }
    sort(query.begin(),query.end());
    int l = 0, r = 0;
    auto f = [&](int i){
        swap(x[a[i]], x[b[i]]);
        swap(y[x[a[i]]], y[x[b[i]]]);
    };
    auto g = [&](int i){
        int tl = y[a[i]], tr = y[b[i]];
        swap(x[tl], x[tr]);
        swap(y[x[tl]], y[x[tr]]);
    };
    for (auto &&X : query) {
        while(X.l < l) g(--l);
        while(r < X.r) f(r++);
        while(l < X.l) g(l++);
        while(X.r < r) f(--r);
        if(t[X.no] == 1) ans[X.no] = x[val[X.no]];
        else ans[X.no] = y[val[X.no]];
    }
    for (auto &&i : ans) printf("%d\n", i+1);
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 7164
final_rank: 3

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<complex>
using namespace std;
typedef long long ll;
#define rep(i,n) for(int i=0;i<n;i++)
#define chmax(a,b) a=max(a,b)
#define chmin(a,b) a=min(a,b)
#define all(x) x.begin(),x.end()
#define N 100010
ll n,k,q;
ll a[N],b[N];
ll f[N],s[N],t[N],x[N];
ll p[N],r[N];//p[i]..i番目にあるもの,r[i]...iがある場所
ll mem[N];
vector<ll> v[N];
int main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cin>>n>>k>>q;
	rep(i,k)cin>>a[i]>>b[i];
	rep(i,q){
		cin>>f[i]>>s[i]>>t[i]>>x[i];
	}
	
	rep(i,q){
		if(f[i]==2)continue;
		v[t[i]].push_back(i);
	}
	rep(i,n+1)p[i]=r[i]=i;
	rep(i,k+1){
		for(auto id:v[i]){
			mem[id]=p[x[id]];
		}
		if(i<k){
			swap(r[p[a[i]]],r[p[b[i]]]);
			swap(p[a[i]],p[b[i]]);
		}
	}
	rep(i,k+1)v[i].clear();
	
	rep(i,q){
		if(f[i]==2)continue;
		v[s[i]-1].push_back(i);
	}
	rep(i,n+1)p[i]=r[i]=i;
	rep(i,k+1){
		for(auto id:v[i]){
			mem[id]=r[mem[id]];
		}
		if(i<k){
			swap(r[p[a[i]]],r[p[b[i]]]);
			swap(p[a[i]],p[b[i]]);
		}
	}
	rep(i,k+1)v[i].clear();
	
	rep(i,q){
		if(f[i]==1)continue;
		v[s[i]-1].push_back(i);
	}
	rep(i,n+1)p[i]=r[i]=i;
	rep(i,k+1){
		for(auto id:v[i]){
			mem[id]=p[x[id]];
		}
		if(i<k){
			swap(r[p[a[i]]],r[p[b[i]]]);
			swap(p[a[i]],p[b[i]]);
		}
	}
	rep(i,k+1)v[i].clear();
	
	rep(i,q){
		if(f[i]==1)continue;
		v[t[i]].push_back(i);
	}
	rep(i,n+1)p[i]=r[i]=i;
	rep(i,k+1){
		for(auto id:v[i]){
			mem[id]=r[mem[id]];
		}
		if(i<k){
			swap(r[p[a[i]]],r[p[b[i]]]);
			swap(p[a[i]],p[b[i]]);
		}
	}
	rep(i,k+1)v[i].clear();
	
	rep(i,q){
		cout<<mem[i]<<"\n";	
	}
}
accuracy: 1
time_ms: 50
memory_kb: 15408
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
using UL=unsigned int;
using LL=long long;
using ULL=unsigned long long;
#define rep(i,n) for(UL i=0; i<(n); i++)

struct Query{ UL l,r,x,i; };
bool cmp_r(const Query& l,const Query& r){ return l.r>r.r; }

UL N,K,Q;
UL S[100000];
UL T[100000];
UL rT[100000];
UL A[100000][2];
vector<Query> Que[2][300];
UL L,R;
UL ans[100000];

void exe(UL l, UL r){
 for(int p=R; p<r; p++) swap(S[A[p][0]],S[A[p][1]]);
 for(int p=R; p>r; p--) swap(S[A[p-1][0]],S[A[p-1][1]]);
 for(int p=L; p<l; p++){
  swap(rT[T[A[p][0]]],rT[T[A[p][1]]]);
  swap(T[A[p][0]],T[A[p][1]]);
 }
 for(int p=L; p>l; p--){
  swap(rT[T[A[p-1][0]]],rT[T[A[p-1][1]]]);
  swap(T[A[p-1][0]],T[A[p-1][1]]);
 }
 L=l; R=r;
}

int main(){
 scanf("%u%u%u",&N,&K,&Q);
 L=R=0;
 rep(i,K) rep(j,2){ scanf("%u",&A[i][j]); A[i][j]--; }
 rep(q,Q){
  UL c,l,r,x; scanf("%u%u%u%u",&c,&l,&r,&x); c--; l--; x--;
  Que[c][l*300/K].push_back(Query{l,r,x,q});
 }
 rep(c,2) rep(i,300) sort(Que[c][i].begin(),Que[c][i].end(),cmp_r);
 rep(c,2){
  rep(i,N)S[i]=i;
  rep(i,N)T[i]=i;
  rep(i,N)rT[i]=i;
  L=R=0;
  rep(i,300){
   for(Query& q:Que[c][i]){
    if(c==0){
     exe(q.l,q.r);
     ans[q.i]=rT[S[q.x]]+1;
    }
    else {
     exe(q.r,q.l);
     ans[q.i]=rT[S[q.x]]+1;
    }
   }
  }
 }
 rep(i,Q) printf("%u\n",ans[i]);
 return 0;
}
accuracy: 1
time_ms: 390
memory_kb: 7996
final_rank: 13