假设一个数在A中的出现位置为x, B中为y
一个数有贡献, 当且仅当
发现是个二维数点的问题, 树套树就可以了
#include<bits/stdc++.h>
#define N 200050
using namespace std;
int read(){ int x; scanf("%d", &x); return x;}
int n, m, a[N], b[N], pos[N];
struct Node{ int ls, rs, sum;}t[N * 200];
int rt[N], tot;
void Modify(int &x, int l, int r, int pos, int val){
if(!x) x = ++tot; t[x].sum += val;
if(l == r) return; int mid = (l+r) >> 1;
if(pos <= mid) Modify(t[x].ls, l, mid, pos, val);
else Modify(t[x].rs, mid+1, r, pos, val);
}
int Quary(int x, int l, int r, int L, int R){
if(!x) return 0; if(L<=l && r<=R) return t[x].sum;
int mid = (l+r) >> 1, ans = 0;
if(L<=mid) ans += Quary(t[x].ls, l, mid, L, R);
if(R>mid) ans += Quary(t[x].rs, mid+1, r, L, R);
return ans;
}
void Add(int x, int y, int val){
for(;x<=n;x+=x&-x) Modify(rt[x], 1, n, y, val);
}
int Ask(int x, int L, int R){
int ans = 0; for(;x;x-=x&-x) ans += Quary(rt[x], 1, n, L, R);
return ans;
}
int Qu(int l1, int r1, int l2, int r2){
return Ask(r1, l2, r2) - Ask(l1-1, l2, r2);
}
int main(){
n = read(), m = read();
for(int i=1; i<=n; i++) a[i] = read(), pos[a[i]] = i;
for(int i=1; i<=n; i++){ b[i] = read(); Add(pos[b[i]], i, 1);}
while(m--){
int op = read();
if(op == 1){
int l1 = read(), r1 = read(), l2 = read(), r2 = read();
int ans = Qu(l1, r1, l2, r2); printf("%d\n", ans);
}
if(op == 2){
int x = read(), y = read();
Add(pos[b[x]], x, -1); Add(pos[b[y]], y, -1);
swap(b[x], b[y]);
Add(pos[b[x]], x, 1); Add(pos[b[y]], y, 1);
}
} return 0;
}