codeforces669E【CDQ分治】

地址
很模板的CDQ分治题。
需要考虑操作编号,操作时间,操作权值。
对于询问要找同时小于编号和时间的操作才影响当前的询问。然后搞一下就行了。。
甚至CDQ分治不用也行,树套树。。。
还是很好理解的,外层权值,内层时间。
cf上路人的有点NB的树套树代码

map<int, map<int, int>> tree;
 
void update(int x, int a, int delta) {
    for (int i = x; i <= (int)1e9 + 15; i += i & -i) {
        tree[a][i] += delta;
    }
}
 
int query(int x, int a) {
    int ans = 0;
    for (int i = x; i > 0; i -= i & -i) {
        ans += tree[a][i];
    }
    return ans;
}

----------------------------------------------------------------------

if (t == 1) {
   update(x, a, 1);
} else if (t == 2) {
    update(x, a, -1);
} else {
     cout << query(x, a) << endl;
}

自己写的CDQ分治代码

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
typedef long long ll;
const ll mod = 1e9+7;
int Case = 1;
int n, m;
struct node{
    int x, y, z;
    int id, op;
}cc[maxn];
bool cmp1(node a, node b) {
    if(a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}
bool cmp2(node a, node b)  {
    return a.y < b.y;
}
int res[maxn];
int num[maxn];
void cdq(int l, int r) {
    if(l == r)return;
    int mid = (l+r)/2;
    cdq(l, mid);cdq(mid+1, r);
    sort(cc+l, cc+1+mid, cmp2);
    sort(cc+1+mid, cc+r+1, cmp2);
    int ii = l, jj = mid+1;
    while(jj <= r) {
        while(cc[ii].y < cc[jj].y && ii <= mid) {
            if(cc[ii].op == 1) num[cc[ii].z]++;
            else if(cc[ii].op == 2) num[cc[ii].z]--;
            ii++;
        }
        if(cc[jj].op == 3) res[cc[jj].id] += num[cc[jj].z];
        jj++;
    }
    for(int i = l; i < ii; i++) {
        if(cc[i].op == 1) num[cc[i].z]--;
            else if(cc[i].op == 2) num[cc[i].z]++;
    }
}
vector<int>ve;
int getid(int x) {
    return lower_bound(ve.begin(), ve.end(), x) - ve.begin()+1;
}
void solve() {
    scanf("%d",&n);int cnt = 0;
    for(int i = 1; i <= n; i++) {
        scanf("%d%d%d", &cc[i].op, &cc[i].y, &cc[i].z);
        if(cc[i].op == 3) cc[i].id = ++cnt;
        cc[i].x = i;ve.push_back(cc[i].z);
    }
    sort(ve.begin(), ve.end());
    ve.erase(unique(ve.begin(), ve.end()), ve.end());
    for(int i = 1; i <= n; i++) cc[i].z = getid(cc[i].z);
    sort(cc+1, cc+1+n, cmp1);
    //for(int i = 1; i <= n; i++) printf("%d %d\n", cc[i].op, cc[i].x);
    cdq(1, n);
    for(int i = 1; i <= cnt; i++) {
        printf("%d\n", res[i]);
    }
    return;
}
int main() {
    //g++ -std=c++11 -o2 1.cpp -o f && ./f < in.txt
    //ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt","w",stdout);
#endif
while(Case--) {
    solve();
    }
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39921637/article/details/96486011
今日推荐