This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0425"
#include "../memo/macro.hpp"
#include "../data_structure/Mo.cpp"
int main(void) {
ll n, k, q;
cin >> n >> k >> q;
vector<ll> a(k), b(k);
REP(i, k) cin >> a[i] >> b[i], a[i]--, b[i]--;
vector<ll> type(q), s(q), t(q), x(q);
REP(i, q) cin >> type[i] >> s[i] >> t[i] >> x[i], s[i]--, t[i]--, x[i]--;
vector<ll> c(n), d(n);
iota(ALL(c), 0);
iota(ALL(d), 0);
auto moveL = [&](ll v) {
ll p1 = d[a[v]], p2 = d[b[v]];
swap(c[p1], c[p2]);
swap(d[c[p1]], d[c[p2]]);
};
auto moveR = [&](ll v) {
ll p1 = a[v], p2 = b[v];
swap(c[p1], c[p2]);
swap(d[c[p1]], d[c[p2]]);
};
Mo mo(k, moveL, moveR, moveL, moveR);
REP(i, q) mo.insert(s[i], t[i]+1);
mo.build();
vector<ll> ans(q);
REP(i, q) {
ll idx = mo.process();
if(type[idx] == 1) ans[idx] = c[x[idx]];
else ans[idx] = d[x[idx]];
}
REP(i, q) cout << ans[i]+1 << "\n";
cout << flush;
return 0;
}
#line 1 "test/aoj0425.test.cpp"
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0425"
#line 1 "memo/macro.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<ll, ll>;
#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
template<typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template<typename T> void chmax(T &a, const T &b) { a = max(a, b); }
struct FastIO {FastIO() { cin.tie(0); ios::sync_with_stdio(0); }}fastiofastio;
const ll INF = 1LL<<60;
#line 1 "data_structure/Mo.cpp"
// BEGIN CUT
struct Mo {
int width;
int nl, nr, ptr;
vector<bool> used;
vector<int> left, right, order;
using F = function<void(int)>;
F expandL, expandR, shrinkL, shrinkR;
// クエリの区間 \subseteq [0,n)
Mo(int n, F el, F er, F sl, F sr) : width((int)sqrt(n)), nl(0), nr(0), ptr(0), used(n), expandL(el), expandR(er), shrinkL(sl), shrinkR(sr) {}
// [l, r)
void insert(int l, int r) {
left.push_back(l);
right.push_back(r);
}
void build() {
order.resize(left.size());
iota(ALL(order), 0);
sort(ALL(order), [&](int a, int b) {
if(left[a] / width != left[b] / width) return left[a] < left[b];
return right[a] < right[b];
});
}
// クエリを1つ進め、クエリのidを返す
int process() {
if(ptr == (ll)order.size()) return -1;
const auto id = order[ptr];
while(nl > left[id]) expandL(--nl);
while(nr < right[id]) expandR(nr++);
while(nl < left[id]) shrinkL(nl++);
while(nr > right[id]) shrinkR(--nr);
return order[ptr++];
}
};
/* 区間に対するオフラインクエリ 区間の伸縮が高速にできる場合使えるかも
部分木クエリとか辺属性パスクエリとかでもオイラーツアーで数列にすればok */
// END CUT
namespace cf221div1d {
// 部分木クエリを行きがけ順に並べることで数列に置き換えてMo
void solve() {
ll n, m;
cin >> n >> m;
vector<ll> c(n);
REP(i, n) cin >> c[i];
vector<vector<ll>> g(n);
REP(i, n-1) {
ll a, b;
cin >> a >> b;
a--, b--;
g[a].push_back(b);
g[b].push_back(a);
}
ll ptr = 0;
vector<ll> in(n), out(n), rev(n);
function<void(ll,ll)> dfs = [&](ll v, ll p) {
rev[ptr] = v;
in[v] = ptr++;
for(auto to: g[v]) if(to != p) dfs(to, v);
out[v] = ptr;
};
dfs(0, -1);
vector<ll> color(100000), sum(100001);
auto add = [&](ll idx) {
++color[c[rev[idx]]]; // idxに対応する頂点の分
++sum[color[c[rev[idx]]]];
};
auto del = [&](ll idx) {
--sum[color[c[rev[idx]]]];
--color[c[rev[idx]]];
};
Mo mo(n, add, add, del, del);
vector<ll> v(m), k(m);
REP(i, m) {
cin >> v[i] >> k[i];
--v[i];
mo.insert(in[v[i]], out[v[i]]);
}
mo.build();
vector<ll> ans(m);
REP(i, m) {
ll idx = mo.process();
ans[idx] = sum[k[idx]];
}
REP(i, m) cout << ans[i] << "\n";
}
}
namespace ABC014D {
// 辺属性のパスクエリはオイラーツアーして数列に置き換える
// 辺を奇数回目に訪れるときに追加,偶数回目で削除をする
void solve() {
ll n;
cin >> n;
vector<vector<ll>> g(n);
REP(i, n-1) {
ll x, y;
cin >> x >> y;
x--, y--;
g[x].push_back(y);
g[y].push_back(x);
}
// オイラーツアー
ll ptr = 1;
vector<ll> tour(2*n-1), in(n);
function<void(ll,ll)> euler_tour = [&](ll v, ll p) {
in[v] = ptr-1;
for(auto to: g[v]) {
if(to == p) continue;
tour[ptr++] = to;
euler_tour(to, v);
}
if(p != -1) tour[ptr++] = p;
};
euler_tour(0, -1);
// mapでやるとlogが重かったので辺→intの前計算をしてO(1)にした
ll mp_idx = 0;
map<PII,int> mp;
FOR(i, 1, 2*n-1) {
PII e({tour[i-1], tour[i]});
if(e.first > e.second) swap(e.first, e.second);
if(mp.find(e) == mp.end()) mp[e] = mp_idx++;
}
vector<ll> v_edge(2*n-2);
FOR(i, 1, 2*n-1) {
PII e(tour[i-1], tour[i]);
if(e.first > e.second) swap(e.first, e.second);
v_edge[i-1] = mp[e];
}
// add,delのidxではなく辺(tour[idx+1],tour[idx])の訪問回数を見る
ll sum = 0;
vector<bool> parity(n-1);
auto add = [&](ll idx) {
ll e = v_edge[idx];
parity[e] = !parity[e];
if(parity[e]) {
sum++;
} else {
sum--;
}
};
auto del = [&](ll idx) {
ll e = v_edge[idx];
parity[e] = !parity[e];
if(parity[e]) {
sum++;
} else {
sum--;
}
};
Mo mo(2*n-1, add, add, del, del);
ll q;
cin >> q;
REP(i, q) {
ll a, b;
cin >> a >> b;
a--, b--;
ll ta = in[a], tb = in[b];
if(ta > tb) swap(ta, tb);
// パスa,bについてのクエリは[in[a],in[b])を見る
mo.insert(ta, tb);
}
mo.build();
vector<ll> ans(q);
REP(i, q) {
ll idx = mo.process();
ans[idx] = sum;
}
REP(i, q) cout << ans[i]+1 << "\n";
}
};
#line 4 "test/aoj0425.test.cpp"
int main(void) {
ll n, k, q;
cin >> n >> k >> q;
vector<ll> a(k), b(k);
REP(i, k) cin >> a[i] >> b[i], a[i]--, b[i]--;
vector<ll> type(q), s(q), t(q), x(q);
REP(i, q) cin >> type[i] >> s[i] >> t[i] >> x[i], s[i]--, t[i]--, x[i]--;
vector<ll> c(n), d(n);
iota(ALL(c), 0);
iota(ALL(d), 0);
auto moveL = [&](ll v) {
ll p1 = d[a[v]], p2 = d[b[v]];
swap(c[p1], c[p2]);
swap(d[c[p1]], d[c[p2]]);
};
auto moveR = [&](ll v) {
ll p1 = a[v], p2 = b[v];
swap(c[p1], c[p2]);
swap(d[c[p1]], d[c[p2]]);
};
Mo mo(k, moveL, moveR, moveL, moveR);
REP(i, q) mo.insert(s[i], t[i]+1);
mo.build();
vector<ll> ans(q);
REP(i, q) {
ll idx = mo.process();
if(type[idx] == 1) ans[idx] = c[x[idx]];
else ans[idx] = d[x[idx]];
}
REP(i, q) cout << ans[i]+1 << "\n";
cout << flush;
return 0;
}