caioj1099: 线段树(元问题)线性结构求极值和修改

来源:互联网 发布:淘宝客服找不到人 编辑:程序博客网 时间:2024/04/28 17:12

caioj1099: 线段树(元问题)线性结构求极值和修改

20171109更新详解

时间限制: 1 Sec 内存限制: 128 MB
【题意】
给出N个数,两种操作:
1、C x y:修改第x个数的值为y;
2、P x y:求第x到第y个的最大值,注:x未必比y小
【输入格式】
第一行输入N和M(0

Solution

如果纯模拟,时间肯定会超
线段树的元问题
c++翻译一下pascal的线段树模板,我来做一个pascal版本的线段树模板吧。
话说noip还是报了pascal,c++和pascal的翻译水平越来越熟练了~~
话说读入问题昨天找了许长时间都找不出来错误,,,,害死人
(c++我直接在caioj复制过来了,应该不侵权吧…)

Code

type  node=record    l,r,lc,rc,c:longint;//l,r为范围,lc,rc为左孩子与右孩子,c为特征值  end;var tr:array[0..410000]of node;    a:array[0..210000]of longint;    len,i,j,n,m,x,y:longint;    ss:char;function mymax(p,q:longint):longint;begin  if p>q then exit(p)  else exit(q);end;procedure buildtree(l,r:longint);var now,mid:longint;begin  inc(len); //申请管理者  now:=len; //记录当前编号  tr[now].l:=l; tr[now].r:=r; tr[now].lc:=-1; tr[now].rc:=-1;//初始  if l=r then tr[now].c:=a[l]  //只管一个人,则对应c  else  begin              //若管理人数大于等于2    mid:=(l+r)div 2;    tr[now].lc:=len+1;buildtree(l,mid);//编号,l,mid给左孩子    tr[now].rc:=len+1;buildtree(mid+1,r);//同上    tr[now].c:=mymax(tr[tr[now].lc].c,tr[tr[now].rc].c);//上述就位后询问最大值为多少并记录  end;end;procedure change(now,x,k:longint);  //告诉头领(now),x的位置改成k//修改的是管理者不是员工的值var mid,lc,rc:longint;begin  if tr[now].l=tr[now].r then begin tr[now].c:=k; exit; end; //找到最基层  lc:=tr[now].lc;   rc:=tr[now].rc;  mid:=(tr[now].l+tr[now].r)div 2;  if x<=mid then change(lc,x,k)  else  if mid+1<=x then change(rc,x,k);  tr[now].c:=mymax(tr[lc].c,tr[rc].c);//改完后询问维护最大值end;function findmax(now,l,r:longint):longint;//var lc,rc,mid:longint;begin  if (l=tr[now].l)and(tr[now].r=r) then exit(tr[now].c);//找到就输出  lc:=tr[now].lc;   rc:=tr[now].rc;  mid:=(tr[now].l+tr[now].r)div 2;  if r<=mid then exit(findmax(lc,l,r))  else if mid+1<=l then exit(findmax(rc,l,r))  //下方为一部分在左child与右child里  else exit(mymax(findmax(lc,l,mid),findmax(rc,mid+1,r)));end;begin  readln(n,m);  for i:=1 to n do  begin    if i<>n then    read(a[i])    else readln(a[i]); //注意读入,害死人qwq  end;  //读入数据  len:=0; buildtree(1,n);  //初始管理员为0,在1,n范围建树  for i:=1 to m do  begin    read(ss);    readln(x,y);//注意读入!!!    if ss='C' then change(1,x,y)    else    begin      if (x>y) then writeln(findmax(1,y,x))      else writeln(findmax(1,x,y));    end;  end;end.

c++版本放下面

上面的图片来自caioj,pascal版本为翻译

阅读全文
1 0