# 【題解】Codeforces 1093E. Intersection of Permutations

【題目敘述】http://codeforces.com/contest/1093/problem/E
【解題想法】cdq分治

```#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct node{
int x, y, z;
int ans, id, cnt, flag;
};
vector <node> v;
int n, m, a, b, c, d, bit[200005], ans[200005], nx[200005], ny[200005], pos[200005];

bool cmp1(node a, node b){
if (a.x != b.x) return a.x < b.x;
if (a.y != b.y) return a.y < b.y;
return a.z < b.z;
}
bool cmp2(node a, node b){
if (a.y != b.y) return a.y < b.y;
return a.z < b.z;
}
void update(int x, int d){
while (x < 200005){
bit[x] += d;
x += x & (-x);
}
}
int query(int x){
int ret = 0;
while (x){
ret += bit[x];
x -= x & (-x);
}
return ret;
}
void cdq(int l, int r){
//cout << l << " " << r << endl;
if (l == r) return;
int mid = (l+r) >> 1;
cdq(l, mid);
cdq(mid+1, r);
sort(v.begin()+l, v.begin()+mid+1, cmp2);
sort(v.begin()+mid+1, v.begin()+r+1, cmp2);
int p = l;
for (int i = mid+1; i <= r; i++){
while (p <= mid && v[p].y <= v[i].y){
update(v[p].z, v[p].cnt);
p++;
}
v[i].ans += query(v[i].z);
}
for (int i = l; i < p; i++){
update(v[i].z, -v[i].cnt);
}

}

int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++){
cin >> a;
nx[a] = i;
}
for (int i = 1; i <= n; i++){
cin >> a;
pos[i] = a;
ny[a] = i;
v.push_back({nx[a], i, 1, 0, 0, 1, 0});
}
int type, idx = 1;
for (int i = 2; i <= m+1; i++){
cin >> type;
if (type == 2){
cin >> a >> b;
v.push_back({nx[pos[a]], ny[pos[a]], i, 0, 0, -1, 0});
v.push_back({nx[pos[b]], ny[pos[b]], i, 0, 0, -1, 0});
swap(ny[pos[a]], ny[pos[b]]);
swap(pos[a], pos[b]);
v.push_back({nx[pos[a]], ny[pos[a]], i, 0, 0, 1, 0});
v.push_back({nx[pos[b]], ny[pos[b]], i, 0, 0, 1, 0});
}
else{
cin >> a >> b >> c >> d;
v.push_back({b, d, i, 0, idx, 0, 1});
v.push_back({a-1, d, i, 0, idx, 0, -1});
v.push_back({b, c-1, i, 0, idx, 0, -1});
v.push_back({a-1, c-1, i, 0, idx, 0, 1});
idx++;
}
}
sort(v.begin(), v.end(), cmp1);
cdq(0, v.size()-1);
for (auto i:v){
//cout << i.x << " " << i.y << " " << i.z << " " << i.ans << " " << i.id << " " << i.cnt << " " << i.flag << endl;
ans[i.id] += i.ans * i.flag;
}
for (int i = 1; i < idx; i++){
cout << ans[i] << "\n";
}
}
```