Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef LOCAL
- //#include "rang.hpp"
- //using namespace rang;
- #endif
- #include <bits/stdc++.h>
- using namespace std;
- #define fast_read ios::sync_with_stdio(false); cin.tie(nullptr);
- #ifdef LOCAL
- #define see(x) cout <<"<DBG> " << #x << ": " << (x) << endl
- #endif
- #ifndef LOCAL
- #define see(x)
- #endif
- template<typename T> void dprintln(const T &t) { cout << t << endl; } // for debug use
- template<typename T, typename ...Args> void dprintln(const T &t, const Args &...rest) { cout << t << ' '; dprintln(rest...); }
- template<typename T> void println(const T &t) { cout << t << '\n'; }
- template<typename T, typename ...Args> void println(const T &t, const Args &...rest) { cout << t << ' '; println(rest...); }
- template<typename T> void print(const T &t) { cout << t << ' '; }
- template<typename T, typename ...Args> void print(const T &t, const Args &...rest) { cout << t; print(rest...); }
- // this overload is chosen when there's only one argument
- template<class T> void scan(T &t) { cin >> t; }
- template<class T, class ...Args> void scan(T &a, Args &...rest) { cin >> a; scan(rest...); }
- using ll = long long;
- using vl = vector<ll>;
- using vi = vector<int>;
- using pii = pair<int,int>;
- using vb = vector<bool>;
- using vpii = vector<pii>;
- #define rng(i, a, b) for(int i = (a); i < (b); ++i)
- #define dwn(i, b, a) for (int i = (b); i >= (a); i--)
- #define rep(n) for(int _ = 0, __ = (int)n; _ < __; _++)
- #define stp(i, a, b, c) for (int i = (a); i < (b); i += (c))
- #define FOR(x, cont) for (auto &x: cont)
- #define all(x) begin(x), end(x)
- #define pb push_back
- #define mp make_pair
- #define eb emplace_back
- #define SZ(x) (int)(x).size()
- #define pq(T,COMP) priority_queue<T, vector<T>, COMP>
- #define popcnt(x) __builtin_popcount((x))
- #define SET(arr, v) memset(arr, (v), sizeof (arr))
- #define UNIQ(vec) (vec).erase(unique(all(vec)), end(vec))
- //auto bet = [](const ll x, const ll y, const ll i) {
- // return x <= i && i <= y;
- //};
- //inline int h_bit(unsigned int x) {
- // return 31 - __builtin_clz(x);
- //}
- //inline int h_bitll(unsigned long long x) {
- // return 63 - __builtin_clzll(x);
- //}
- //
- //struct frac{
- // using ll = long long;
- // ll fz, fm;
- // frac() = default;
- //
- // frac(ll fz, ll fm) { // 构造函数变量名最好不要跟类成员名一样!
- // assert(fm != 0);
- // if (fm < 0) fm *= -1, fz *= -1;
- // ll g = __gcd(abs(fz), fm);
- // fz /= g, fm /= g;
- // this->fz = fz, this->fm = fm;
- // }
- //
- // frac(ll x):fz(x),fm(1){} // implicit conversion
- //
- // frac operator*(const frac &other)const{
- // return {fz * other.fz, fm * other.fm};
- // }
- //
- // frac operator-()const{
- // return {-fz, fm};
- // }
- // frac operator-(const frac &other)const{
- // return *this + (-other);
- // }
- // frac operator+(const frac &other)const{
- // ll _fz = fz * other.fm + fm * other.fz;
- // ll _fm = fm * other.fm;
- // return {_fz, _fm};
- // }
- // bool operator==(const frac &other)const{
- // return other.fz == fz && other.fm == fm;
- // }
- // bool operator<(const frac &other)const{
- // return fz * other.fm < other.fz * fm;
- // }
- // bool operator>(const frac &other)const{
- // return fz * other.fm > other.fz * fm;
- // }
- // bool operator>=(const frac &other)const{
- // return !(*this < other);
- // }
- // bool operator<=(const frac &other)const{
- // return !(*this > other);
- // }
- // frac operator/(const int &x)const{
- // return {fz, fm * x};
- // }
- // double to_double() const {
- // return fz / (double)fm;
- // }
- //
- //};
- template <typename T>
- struct bit {
- vector<T> a;
- explicit bit(int n, int v = 0) {
- a.resize(n + 1);
- if(v != 0) {
- for (int i = 1; i <= n; ++i) a[i] = v;
- }
- }
- T sum(T x) {
- T res = 0;
- while (x) {
- res += a[x];
- x -= x & -x;
- }
- return res;
- }
- T sum(int l, int r) {
- if (l > r) return 0;
- return sum(r) - sum(l - 1);
- }
- void add(int x, T v) {
- while (x < a.size()) {
- a[x] += v;
- x += x & -x;
- }
- }
- void clear(){
- fill(a.begin(), a.end(), 0);
- }
- };
- vi get_prime(int n) {
- vi minp(n + 1), p;
- for (int i = 2; i <= n; i++) {
- if (!minp[i]) {
- minp[i] = i;
- p.pb(i);
- }
- FOR(x, p) {
- if (x <= minp[i] && x * i <= n)
- minp[x * i] = x;
- else break;
- }
- }
- return p;
- }
- const int mod = 1000000007;
- inline void add_mod(ll &x, const ll &y) {
- x += y;
- if (x >= mod) x -= mod;
- }
- void sub_mod(ll &x, const ll &y) {
- x -= y;
- if (x < 0) x += mod;
- }
- // alias templates
- template<typename T> using vv = vector<vector<T>>;
- template <typename T1, typename T2 = T1> using vp = vector<pair<T1,T2>>;
- template<typename T, int n> using va = vector<array<T,n>>;
- using vec = vector<ll>;
- using mat = vector<vec>;
- mat get_I(int n) {
- mat res(n, vec(n));
- for (int i = 0; i < n; i++)
- res[i][i] = 1;
- return res;
- }
- mat operator*(const mat &a, const mat &b) {
- mat c(a.size(), vec(b[0].size()));
- for (size_t i = 0; i < a.size(); i++) {
- for (size_t j = 0; j < a[0].size(); j++) {
- if (a[i][j]) { // optimization for sparse matrix
- for (size_t k = 0; k < b[0].size(); k++) {
- add_mod(c[i][k], a[i][j] * b[j][k] % mod);
- }
- }
- }
- }
- return c;
- }
- vec operator*(const mat &a, const vec &b) {
- vec c(a.size());
- for (size_t i = 0; i < a.size(); i++) {
- for (size_t j = 0; j < a[0].size(); j++) {
- add_mod(c[i], a[i][j] * b[j] % mod);
- }
- }
- return c;
- }
- mat pow(mat a, ll n) {
- mat res(a.size(), vec(a[0].size()));
- for (size_t i = 0; i < a.size(); i++) {
- res[i][i] = 1;
- }
- while (n) {
- if (n & 1) {
- res = res * a;
- }
- a = a * a;
- n >>= 1;
- }
- return res;
- }
- //union-find 并查集
- struct UF{
- vi par;
- explicit UF(int n) {
- par.assign(n + 1, 0);
- rng (i, 1, n + 1) par[i] = i;
- }
- int find(int x) {
- return x == par[x] ? x : par[x] = find(par[x]);
- }
- void unite(int x, int y) {
- par[find(x)] = find(y);
- }
- };
- vi get_popcnt(int n) {
- vi res(n + 1);
- rng (i, 0, n) {
- if (i * 2 <= n) res[i * 2] = res[i];
- if ((i & 1) == 0) res[i + 1] = res[i] + 1;
- }
- return res;
- }
- /**** SUPER MACROs ****/
- #define FAIL {println("NO"); return 0;}
- const int N = 2e5+5, M = 1005;
- vv<int> g(N);
- int fa[N][18];
- int dep[N];
- void dfs(int u, int f) {
- fa[u][0] = f;
- dep[u] = dep[f] + 1;
- rng (i, 1, 18) {
- fa[u][i] = fa[fa[u][i-1]][i-1];
- }
- FOR(v, g[u]) if(v!=f) {
- dfs(v, u);
- }
- }
- int lca(int u, int v){
- if (dep[u] < dep[v]) swap(u, v);
- int dif = dep[u] - dep[v];
- rng(i, 0, 18) {
- if (dif & 1 << i) {
- u = fa[u][i];
- }
- }
- if (u == v) return u;
- dwn(i, 17, 0) {
- if (fa[u][i] != fa[v][i]) {
- u = fa[u][i];
- v = fa[v][i];
- }
- }
- return fa[u][0];
- }
- vi check(int a, int b, int c, int d) {
- if (a == 0 && b == 0) return {c, d};
- int x[4] = {a, b, c, d};
- rng(i, 0, 3) rng(j, i+1, 4) {
- int u = lca(x[i], x[j]);
- vi ans;
- rng(k, 0, 4) {
- if (k != i && k != j) {
- int t = x[k];
- if (lca(t, u) == u && (lca(t, x[i]) == t || lca(t, x[j]) == t)) {
- ans.pb(t);
- } else break;
- }
- }
- if (SZ(ans) == 2) {
- return ans;
- }
- }
- return {-1,-1};
- }
- struct node{
- bool ok;
- int u, v;
- }tree[N*4];
- int leaf[N];
- int p[N];
- int v[N]; // 值所在的节点编号
- void push_up(int id){
- auto & f = tree[id], lson = tree[id * 2], rson = tree[id * 2 + 1];
- if (lson.ok && rson.ok) {
- auto res = check(lson.u, lson.v, rson.u, rson.v);
- if (res[0] != -1) {
- f.ok = true;
- f.u = res[0];
- f.v = res[1];
- }
- }
- }
- void build(int id, int l, int r) {
- if (l == r) {
- leaf[l] = id;
- tree[id].u = tree[id].v = v[l];
- tree[id].ok = true;
- return;
- }
- int mid = (l + r) / 2;
- build(id * 2, l, mid);
- build(id * 2 + 1, mid + 1, r);
- push_up(id);
- }
- void work(int i) {
- int id = leaf[p[i]];
- tree[id].u = tree[id].v = i;
- while(id != 1){
- id /= 2;
- push_up(id);
- }
- }
- void upd(int i, int j) {
- swap(p[i], p[j]);
- work(i);
- work(j);
- }
- int query(int id, int l, int r, int u, int v) {
- if (tree[id].ok) {
- auto t = check(u, v, tree[id].u, tree[id].v);
- if (t[0] != -1) return r - l + 1;
- if (l == r) return 0;
- }
- int mid = (l + r) / 2;
- auto &lson = tree[id * 2];
- if (lson.ok) {
- auto t = check(u, v, lson.u, lson.v);
- if (t[0] != -1) {
- return mid - l + 1 + query(id * 2 + 1, mid + 1, r, t[0], t[1]);
- }
- }
- return query(id * 2 + 1, l, mid, u, v);
- }
- int main() {
- fast_read
- #ifdef LOCAL
- freopen("main.in", "r", stdin);
- // ifstream in("main.in");
- // auto cinbuf = std::cin.rdbuf(in.rdbuf()); //C++ style
- // freopen("main.out", "w", stdout);
- #endif
- int n; cin >> n;
- vi p(n+1); rng(i, 1, n+1) cin >> p[i], v[p[i]] = i;
- rng(i, 2, n + 1) {
- int x; cin >> x;
- g[x].pb(i);
- g[i].pb(x);
- }
- build(1, 0, n);
- dfs(1, 1);
- int q; cin >> q;
- rep(q) {
- int t, i, j;
- scan(t);
- if (t == 1) {
- scan(i, j);
- upd(i, j);
- }
- else {
- println(query(1, 0, n, 0, 0));
- }
- }
- #ifdef LOCAL
- cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
- // cin.rdbuf(cinbuf);
- // system("PAUSE");
- #endif
- return 0;
- }
Add Comment
Please, Sign In to add comment