最大值

本文介绍了一个程序实现,用于处理操作序列,包括添加和询问序列中最后部分的最大值。通过使用线段树维护区间最大值,有效地解决了查询操作的需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最大值
maxnumber/.IN/.OUT/.PAS/.EXE
问题描述
给定一列正整数a1, a2, a3, …, an,每一个数都在0 ~ p – 1 之间。可以对这列数进行

两种操作:

添加操作:向序列后添加一个数,序列长度变成n + 1。

 询问操作:询问这个序列中最后L 个数中最大的数是多少。
程序运行的最开始,整数序列为空。写一个程序,读入操作的序列,并输出询问操作的
答案。
输入
输入文件maxnumber.in 的第一行有两个正整数,m (1 ≤ m ≤ 200000 )和p (1 ≤
p ≤ 2 * 109)。
在接下来的m 行中,每一行表示一个操作。如果该行的内容是Q L,则表示这个操作
是询问序列中最后L 个数的最大数是多少;如果是A t (0 ≤ t < p),则表示向序列后面加
一个数,加入的数是(t + a)除以p的余数。其中,t 是输入的参数,a 是在这个添加操作之
前最后一个询问操作的答案(如果之前没有询问操作,则a = 0)。

第一个操作一定是添加操作。对于询问操作,L > 0 且不超过当前序列的长度。

输出
请将输出写入文件maxnumber.out。对于每一个询问操作,输出一行。该行只有一
个数,即序列中最后L 个数的最大数。


线段树维护区间最大值即可

虽然与题上相矛盾,但是输入数据中有负数


program maxnumber;
var
  all,l,tot,m,i,j,k,a:longint;
  t,p:int64;
  left,right,point:array [0..4000001] of longint;
  order:char;

procedure insert (who,p,l,r,now:longint);
begin
  if l=r then
    begin
      point[now]:=p;
      exit;
    end;
  if left[now]=0 then
    begin
      inc(all);
      left[now]:=all;
    end;
  if right[now]=0 then
    begin
      inc(all);
      right[now]:=all;
    end;
  if who<=(l+r) div 2 then
    insert(who,p,l,(l+r) div 2,left[now])
                      else
    insert(who,p,(l+r) div 2+1,r,right[now]);
  if point[left[now]]>point[right[now]] then point[now]:=point[left[now]]
                                        else point[now]:=point[right[now]];
end;

function find (s,e,l,r,now:longint):longint;
var
  a,b,mid:longint;
begin
  if (s=l)and(e=r) then exit(point[now]);
  if left[now]=0 then
    begin
      inc(all);
      left[now]:=all;
    end;
  if right[now]=0 then
    begin
      inc(all);
      right[now]:=all;
    end;
  mid:=(l+r) div 2;
  if e<=mid then exit(find(s,e,l,mid,left[now]))
            else
  if s>mid then exit(find(s,e,mid+1,r,right[now]))
           else
    begin
      a:=find(s,mid,l,mid,left[now]);
      b:=find(mid+1,e,mid+1,r,right[now]);
      if a>b then exit(a)
             else exit(b);
    end;
end;

begin
  assign(input,'maxnumber.in');
  reset(input);
  assign(output,'maxnumber.out');
  rewrite(output);
  readln(m,p);
  for i:=1 to m do
    begin
      read(order);
      if order='A' then
        begin
          read(t);
          t:=(t+a) mod p;
          inc(tot);
          insert(tot,t,1,200000,0);
        end
                   else
        begin
          read(l);
          a:=find(tot-l+1,tot,1,200000,0);
          writeln(a);
        end;
      readln;
    end;
  close(input);
  close(output);
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值