地址
很模板的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;
}