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.