在我们平常使用的分治中,每一个子问题只解决它本身(可以说是封闭的)。
而在cdq分治中,对于划分出来的两个子问题,前一个子问题用来解决后一个子问题而不是它本身。
具体算法流程如下:
1.将整个操作序列分为两个长度相等的部分(分)
2.递归处理前一部分的子问题(治1)
3.计算前一部分的子问题中的修改操作对后一部分子问题的影响(治2)
4.递归处理后一部分子问题(治3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <class T> inline bool scan_d(T &ret) {char c; int sgn;if(c=getchar(),c==EOF) return 0;while(c!='-'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1;ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); ret*=sgn;return 1;}
const int N = 500005;
struct mmp
{
int op, id, l, r;
mmp() {}
mmp(int _op, int _id, int _l, int _r) : op(_op), id(_id), l(_l), r(_r) {}
} q[N];
int ans[N], sum[N << 1], mx;
vector<int> a;
inline bool cmp(const mmp &x, const mmp &y)
{
if(x.r == y.r)
return x.l < y.l;
return x.r > y.r;
}
void add(int x, int val)
{
for(int i = x; i <= mx; i += i & (-i)) sum[i] += val;
}
int getsum(int x, int res = 0)
{
for(int i = x; i > 0; i -= i & (-i)) res += sum[i];
return res;
}
void solve(int l, int r)
{
if(l == r) return;
int m = (l + r) >> 1;
solve(l, m);
solve(m + 1, r);
sort(q + l, q + r + 1, cmp);
for(int i = l; i <= r; i++)
{
if(q[i].id <= m) {
if(q[i].op) add(q[i].l, 1);
}
else {
if(q[i].op == 0)
ans[q[i].id] += getsum(q[i].l);
}
}
for(int i = l; i <= r; i++)
if(q[i].id <= m) {
if(q[i].op) add(q[i].l, -1);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
while(cin >> n)
{
char op;
cin.ignore();
a.clear();
int l, r;
for(int i = 1; i <= n; i++)
{
cin >> op >> l >> r;
if(op == '+') q[i] = {1, i, l, r};
else q[i] = {0, i, l, r};
a.push_back(l);
a.push_back(r);
}
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
for(int i = 1; i <= n; i++)
{
q[i].l = int(lower_bound(a.begin(), a.end(), q[i].l) - a.begin()) + 1;
q[i].r = int(lower_bound(a.begin(), a.end(), q[i].r) - a.begin()) + 1;
}
fill(ans, ans + n + 1, 0);
mx = (int)a.size();
solve(1, n);
sort(q + 1, q + n + 1, [] (const mmp &x, const mmp &y) { return x.id < y.id; });
for(int i = 1; i <= n; i++)
if(!q[i].op) cout << ans[i] << "\n";
}
return 0;
}
/*
9
+ 5 10
+ 7 20
+ 3 15
? 9 12
+ 10 20
? 8 9
+ 6 30
? 8 9
? 9 12
*/
- 版权声明:本文基于《知识共享署名-相同方式共享 3.0 中国大陆许可协议》发布,转载请遵循本协议
- 文章链接:http://www.carlstedt.cn/archives/1437 (转载时请注明本文出处及文章链接)


发表评论
快来吐槽一下吧!