题意:
两种操作 :a,b
a=0:插入一个区间 长度为num 区间范围为[b,b+num] ( num表示为 这条区间的编号 第一个插入的 num=1,第二个插入的 num = 2
a=1:删除第b个区间
插入一个线段 要输出 在这个区间内的区间数量
维护线段左右两端的位置数量 ( 输出 大于等于左端点的数量 减去 大于右端点的数量)
所有的区间分成6种 容斥下就好了
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
typedef long long LL;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN = 410000;//点数的最大值
const int MAXM = 604000;//边数的最大值
const LL INF = 1152921504;
const LL mod= 1e9+7;
int c[MAXN][2],all;
int lowbit(int x)
{
return x&(-x);
}
int sum(int p,int num)
{
int ans=0;
while(p>0)
{
ans+=c[p][num];
p-=lowbit(p);
}
return ans;
}
int add(int p,int val,int num)
{
while(p<=all)
{
c[p][num]+=val;
p+=lowbit(p);
}
}
int a[MAXN],b[MAXN],d[MAXN],to[MAXN];
int main()
{
int n,cas=1;
while(scanf("%d",&n)!=EOF)
{
printf("Case #%d:\n",cas++);
int a0=1;
all=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i],&b[i]);
if(a[i]==0)
{
d[all++]=b[i];
d[all++]=b[i]+a0;
to[a0++]=i;
}
}
sort(d,d+all);
all=unique(d,d+all)-d;
memset(c,0,sizeof(c));
a0=1;
for(int i=0;i<n;i++)
{
if(a[i]==0)
{
int x=lower_bound(d,d+all,b[i])-d+1;
int y=lower_bound(d,d+all,b[i]+a0)-d+1;
int ans1=sum(all,0)-sum(x-1,0);
int ans2=sum(all,1)-sum(y,1);
cout<<ans1-ans2<<endl;
a0++;
add(x,1,0);
add(y,1,1);
}
else
{
int x=lower_bound(d,d+all,b[to[b[i]]])-d+1;
int y=lower_bound(d,d+all,b[to[b[i]]]+b[i])-d+1;
add(x,-1,0);
add(y,-1,1);
}
}
}
return 0;
}
/*
*/