題意:
兩種操作 :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;
}
/*
*/