【題解】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";
    }
}
分享本文 Share with friends