题目描述
考虑一些在实数轴上的线段,你需要写一个程序处理以下两种询问:
1. 询问 + L R 增加一条线段[L,R],你的程序应该输出有多少条线段被该线段包含(非严格)。
2. 询问 - L R 删除一条线段[L,R],如果这条线段不存在则忽略这个询问。
输入
输入文件的每一行都包含一个询问,格式如题目所述,你的程序应该处理到文件结束为止。
输出
对于每一个“+” 询问,输出一个整数,代表被该线段包含的线段条数。
样例输入
+ 1 2
+ 1 2
+ 0 3
- 1 2
+ 1 2
样例输出
0
1
2
1
提示
【数据规模和约定】
对于所有数据,询问的个数不超过25000 个,任意时刻数轴上的线段不超过1000 条, L, R 均在32 位有符号整数的表示范围之内。
一开始,yy出了线段树、离散化等等。后来注意到“任意时刻线段不超过1000条”,发现25000*1000暴力扫一下的复杂度刚好,可怎么维护存线段的数组呢?并且要使得其删除后长度仍<=1000,所以,自然而然地想到了用数组模拟链表。
OI时报 号外:
lwq12138此题爆0,本报记者认为,对lwq12138神犇来说,这种水题不值一写。据悉,目前lwq12138正在研究密码学与原子弹工程,我们有理由相信,不久之后,菲律宾将成为天朝最南端的一个省。
OI时报驻yyhs特派记者 ACTY
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n,x,y,ok,ans,pre,tot;
int l[25005],r[25005],Next[25005];
char s[5];
void add(int x,int y)
{
tot++;
l[tot]=x;
r[tot]=y;
Next[tot]=Next[0];
Next[0]=tot;
}
int main()
{
Next[0]=-1;
while(scanf("%s",s)!=EOF)
{
if(s[0]=='+')
{
scanf("%d%d",&x,&y);
ans=0;
for(int j=Next[0];j!=-1;j=Next[j])
if(x<=l[j]&&y>=r[j]) ans++;
add(x,y);
printf("%d\n",ans);
}
else
{
scanf("%d%d",&x,&y);
pre=0;
for(int j=Next[0];j!=-1;j=Next[j])
{
if(l[j]==x&&r[j]==y)
{
Next[pre]=Next[j];
break;
}
pre=j;
}
}
}
return 0;
}