1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
#pragma GCC optimize("Ofast,no-stack-protector") #pragma GCC target("avx2,fma") #include <cmath> #include <cstdio> #include <vector> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define ULL unsigned long long using namespace std; const int MAXN = 2e5 + 5; const int MAXM = 600;
template <typename T> inline void read(T& x) { x = 0; int f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -f; c = getchar(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); } x *= f; } template <typename T, typename... Args> inline void read (T &x, Args&... Arg) { read (x), read (Arg...); } template <typename T> inline T Abs(T x) { return x < 0 ? -x : x; } template <typename T> inline T Max(T x, T y) { return x > y ? x : y; } template <typename T> inline T Min(T x, T y) { return x < y ? x : y; }
int n, q, m, cnt, siz, ind, tp,nxt[MAXN], col[MAXN], ed[MAXN], stk[MAXN]; struct Node { int opt, x, y, ind; } que[MAXN], ask[MAXN]; vector<int> pos; bool vis[MAXN]; LL sum[MAXN], add[MAXN], num[MAXM][MAXM], a[MAXN];
inline void solve(int m) {
ind = 0, cnt = 0, pos.clear(); memset(vis, 0, sizeof(vis)), memset(col, 0, sizeof(col)); memset(num, 0, sizeof(num)), memset(add, 0, sizeof(add)); for (int i = 1; i <= m; i++) { if (que[i].opt == 1) { if (que[i].x > 1) ask[++cnt] = Node{-1, que[i].x - 1, 1, i}; ask[++cnt] = Node{+1, que[i].y, 1, i}; } else if (que[i].opt == 2) vis[que[i].x] = true; else vis[que[i].x] = vis[que[i].y] = true; }
for (int i = 1, now; i <= n; i++) if (vis[i]) { pos.push_back(i), now = i; do { stk[++tp] = nxt[now], now = nxt[now]; } while (vis[now] != true); ed[pos.size()] = stk[tp]; while (tp) col[stk[tp--]] = ed[pos.size()]; } sort(ask + 1, ask + 1 + cnt, [](const Node& x, const Node& y) { return x.x < y.x; });
for (int i = 1; i <= cnt; i++) { while (ind < ask[i].x) add[col[++ind]]++; for (int j = 1; j <= (int)pos.size(); j++) num[ask[i].ind][j] += ask[i].opt * add[ed[j]]; }
memset(add, 0, sizeof(add)); for (int i = 1, now; i <= m; i++) { if (que[i].opt == 1) { LL res = sum[que[i].y] - sum[que[i].x - 1]; for (int j = 1; j <= (int)pos.size(); j++) res += num[i][j] * add[col[ed[j]]]; printf("%lld\n", res); } else if (que[i].opt == 2) { now = col[que[i].x]; do { add[now] += que[i].y, now = col[nxt[now]]; } while (now != col[que[i].x]); } else swap(nxt[que[i].x], nxt[que[i].y]); } for (int i = 1; i <= n; i++) a[i] += add[col[i]], sum[i] = sum[i - 1] + a[i];
}
int main() {
read(n); for (int i = 1; i <= n; i++) read(a[i]), sum[i] = sum[i - 1] + a[i]; for (int i = 1; i <= n; i++) read(nxt[i]);
read(q), siz = sqrt(q); for (int i = 1; i <= q; i++) { m++, read(que[m].opt, que[m].x, que[m].y); if (m == siz) solve(m), m = 0; } if (m > 0) solve(m);
return 0; }
|