【前缀瞎搞】线段问题

线段问题
From jxpxcsh
描述 Description
有N条线段,已知每条线段的起点和终点(50000以内),然后有M个询问,每次询问一个点(50000以内),求这个点在多少条线段上出现过?
输入格式 InputFormat
第一行N线段条数
接下来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

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.






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值