NOIP2012 classroom渣线段树

1、longint比int64快,计算好不会炸后大胆用会更好。

2、线段树最大编号顶点不等于节点数TAT= =

Tyvj 90分= =

program classroom;

Type
 rec=record
   l,r:longint;
   min,add:longint;
 end;

Var
 a:array[0..1000002] of longint;
 f:array[0..4000000] of rec;
 n,m,d,s,t,all,i,j:longint;
 can:boolean;

Procedure fopen;
  begin
  assign(input,'classroom.in');
  assign(output,'classroom.out');
  reset(input);
  rewrite(output);
end;

Procedure fclose;
  begin
  close(input);
  close(output);
end;

Function mmin(a,b:longint):longint;
  begin
  if a<b then exit(a) else exit(b);
end;

Function mmax(a,b:longint):longint;
  begin
  if a>b then exit(a) else exit(b);
end;

Procedure build(P:longint);
var
 mid:longint;
  begin
  all:=mmax(all,p);
  if f[p].l=f[p].r then
    begin
    f[p].min:=a[f[p].l];
    exit;
  end;
  mid:=(f[p].l+f[p].r) div 2;
  with f[p*2] do
    begin
    l:=f[p].l;
    r:=mid;
  end;

  with f[p*2+1] do
    begin
    l:=mid+1;
    r:=f[p].r;
  end;
  build(p*2);
  build(p*2+1);
  f[p].min:=mmin(f[p*2].min,f[p*2+1].min);
end;

Procedure relax(P:longint);
  begin
  //writeln('Relax(',p,')');
  if p*2>all then begin f[p].add:=0; exit;end;
  with f[p*2] do
    begin
    add:=add+f[p].add;
    min:=min+f[p].add;
  end;
  with f[p*2+1] do
    begin
    add:=add+f[p].add;
    min:=min+f[p].add;
  end;
  f[p].add:=0;
end;

Function Getmin(p,pl,pr:longint):longint;
var
 mid:longint;
  begin
  //writeln('Getmin p=',p,' pl=',pl,' pr=',pr);
  Relax(p);
  if (f[p].l=pl) and (f[p].r=pr) then
    exit(f[p].min);
  mid:=(f[p].l+f[p].r) div 2;
  getmin:=maxlongint;
  if pl<=mid then getmin:=mmin(getmin,getmin(p*2,pl,mmin(pr,mid)));
  if getmin<d then exit;
  if pr>mid then getmin:=mmin(getmin,getmin(p*2+1,mmax(pl,mid+1),pr));
end;

Procedure Add(p,pl,pr:longint;w:longint);
var
 mid:longint;
  begin
 // writeln(' add p=',p,' pl=',pl,' pr=',pr,' w=',w);
  Relax(p);
  if (f[p].l=pl) and (f[p].r=pr) then
    begin
    f[p].min:=f[p].min+w;
    f[p].add:=f[p].add+w;
    exit;
  end;
  mid:=(f[p].l+f[p].r) div 2;
  if pl<=mid then Add(p*2,pl,mmin(pr,mid),w);
  if pr>mid then add(p*2+1,mmax(mid+1,pl),pr,w);
  f[p].min:=mmin(f[p*2].min,f[p*2+1].min);
end;

  begin
  all:=0;
  fopen;
  readln(n,m);
  for i:=1 to n do
    read(a[i]);
  readln;
  f[1].l:=1; f[1].r:=n;
  build(1);
  {for i:=1 to all do
    with f[i] do
      writeln('I=',i,' l=',l,' r=',r,' min=',min);   }
  can:=true;
  for i:=1 to m do
    begin
    readln(d,s,t);
    //writeln('i=',i,' getmin=',getmin(1,s,t));
    if getmin(1,s,t)>=d then
      Add(1,s,t,-d) else
        begin
        writeln(-1);
        writeln(i);
        fclose;
        halt;
      end;
    {for j:=1 to n do write('[',j,']',getmin(1,j,j));
    writeln;}
  end;
  if can then writeln(0);
  fclose;
end.
原文地址:https://www.cnblogs.com/htfy/p/2781466.html