学习了merge函数。
参考题解:http://blog.youkuaiyun.com/v5zsq/article/details/51083826
在ACdream上留下了一页半的wa和tle
总体来说,思路并不难。插入一条线段,就是在线段的起点+1,删除一条线段,就是-1,查询就是+0。在分治的时候,按照线段右端点降序排序。对于左区间的点,更新左端点所在位置。右区间的线段,查询左端点的前缀和统计。如果能像51nod那样查看数据就好了,调代码就方便多了。也不知道哪里写错了,模仿人家的代码写了一发。把离散化的方式换成我比较习惯的方式了。。。。
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&(-x))
const int MAXN = 220022;
int n,tot;
struct node
{
int x,y,cnt,id,ans;
bool operator<(const node& a) const
{
return y > a.y;
}
} p[MAXN],q[MAXN];
bool cmpid(const node& a, const node& b)
{
return a.id < b.id;
}
int bit[MAXN];
void add(int x, int v)
{
while(x <= tot)
{
bit[x] += v;
x += lowbit(x);
}
}
int sum(int x)
{
int ret = 0;
while(x)
{
ret += bit[x];
x -= lowbit(x);
}
return ret;
}
void CDQ(int l, int r)
{
if(l >= r) return;
int mid = (l+r) >> 1;
CDQ(l,mid);
CDQ(mid+1,r);
sort(p+l,p+mid+1);
sort(p+mid+1,p+r+1);
int j = l;
for(int i = mid+1; i <= r; ++i)
{
for(; j <= mid && p[j].y >= p[i].y; ++j)
add(p[j].x,p[j].cnt);
if(!p[i].cnt)
p[i].ans += sum(p[i].x);
}
for(int i = l; i < j; ++i)
add(p[i].x,-p[i].cnt);
merge(p+l,p+mid+1,p+mid+1,p+r+1,q);
for(int i = 0; i < r-l+1; ++i)
p[l+i]=q[i];
}
int res,l[MAXN],r[MAXN];
vector<int> vec;
int getid(int x)
{
return lower_bound(vec.begin(),vec.end(),x)-vec.begin()+1;
}
int main()
{
while(scanf("%d",&n) != EOF)
{
vec.clear();
memset(bit,0,sizeof(bit));
res = 1;
for(int i = 1; i <= n; ++i)
{
p[i].id = i;
p[i].ans = 0;
char s;
int temp;
scanf(" %c",&s);
if(s == 'D')
{
scanf("%d %d",&p[i].x,&p[i].y);
p[i].cnt = 1;
l[res] = p[i].x;
r[res++] = p[i].y;
vec.push_back(p[i].x);
vec.push_back(p[i].y);
}
else if(s == 'Q')
{
scanf("%d %d",&p[i].x,&p[i].y);
p[i].cnt = 0;
vec.push_back(p[i].x);
vec.push_back(p[i].y);
}
else
{
scanf("%d",&temp);
p[i].x = l[temp];
p[i].y = r[temp];
p[i].cnt = -1;
}
}
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()),vec.end());
tot = vec.size();
for(int i = 1; i <= n; ++i)
{
p[i].x = getid(p[i].x);
p[i].y = getid(p[i].y);
}
CDQ(1,n);
sort(p+1,p+1+n,cmpid);
for(int i = 1; i <= n; ++i)
if(!p[i].cnt)
printf("%d\n",p[i].ans);
}
return 0;
}