线段问题
From
jxpxcsh
描述 Description
有N条线段,已知每条线段的起点和终点(50000以内),然后有M个询问,每次询问一个点(50000以内),求这个点在多少条线段上出现过?
输入格式 InputFormat
第一行N线段条数
接下来N行,每行两个数,线段的起点和终点
第N+2行一个数M询问个数
接下来M行,每行一个点
接下来N行,每行两个数,线段的起点和终点
第N+2行一个数M询问个数
接下来M行,每行一个点
输出格式 OutputFormat
对于每个询问,求答案
样例输入 SampleInput
[复制数据]
样例输出 SampleOutput
[复制数据]
数据范围和注释 Hint
N,M<=50000
时间限制 TimeLimitation
各个测试点1s
来源 Source
南雅中学
有点像去年的铺地毯。。。。当然是暴力来写。。
显然o(n*m)会超时。
然后我就不会了。然后就看了题解,然后就长姿势了。。
先设a[i] 表示第i点被覆盖的次数。
观察到对于一个线段[l,r]。
如果加入这个线段后,a[l]..a[r]都会+1。
于是设数组c[i]表示a[i]-a[i-1]。显然给c[i]求个和就是a[i]。
那么加入了[l,r]后
c[l]=c[l]+1
c[r+1]=c[r+1]-1
然后离线O(1)搞出m次查询
时间复杂度o(n)
注意要记录最大的r
有点像去年的铺地毯。。。。当然是暴力来写。。
显然o(n*m)会超时。
然后我就不会了。然后就看了题解,然后就长姿势了。。
先设a[i] 表示第i点被覆盖的次数。
观察到对于一个线段[l,r]。
如果加入这个线段后,a[l]..a[r]都会+1。
于是设数组c[i]表示a[i]-a[i-1]。显然给c[i]求个和就是a[i]。
那么加入了[l,r]后
c[l]=c[l]+1
c[r+1]=c[r+1]-1
然后离线O(1)搞出m次查询
时间复杂度o(n)
注意要记录最大的r
var m,n,i,a,b,k,len:longint;
c,s:array[0..50001]of longint;
begin
//assign(input,'input.in');
//assign(output,'output.out');
//reset(input);rewrite(output);
fillchar(c,sizeof(c),0);
fillchar(s,sizeof(s),0);
readln(n);len:=0;
for i:=1 to n do
begin
readln(a,b);
inc(c[a]);
dec(c[b+1]);
if len<b then len:=b;
end;
s[0]:=c[0];
for i:=1 to len+1 do s[i]:=s[i-1]+c[i];
readln(m);
for i:=1 to m do
begin
readln(k);
writeln(s[k]);
end;
//close(input);close(output);
end.