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.

浙公网安备 33010602011771号