今天做了一道郭华阳出的模拟题,发现竟然和冬令营的答辩试题如出一辙,只改了一点条件,冬令营时就被什么树状数组+平衡树,坐标移位弄得头晕脑胀,一点也没听懂,结果冤家路窄,这次又只拿了40分,T T
重新翻ppt,其实只是优化了转移而已,学了解析几何后,对坐标轴理解更加深刻,这两道题也比较容易理解了。
有m只鼹鼠出现在一个1 ~ n的长条上。对于第k只鼹鼠,我们用t[k], w[k], x[k]来描述。即在t[k]时刻,会有一只分值为w[k]的鼹鼠k出现在位置x[k]上。现在你有一个锤头,每一时刻它都停留在一个位置上。你可以用它不费时间的敲死一只鼹鼠并得到相应的分值。但是每个时刻你的锤头最多只能移动p格。也就是说如果s时刻你在位置pos,那么s + 1时刻你运动到位置pos – p ~ pos + p。
在零时刻你的锤子可以在任意位置。鼹鼠出现的时刻大于0。同时我们保证同一时间同一位置不会有两只鼹鼠出现,因为他们太胖了。
[输入文件]
第一行两个正整数n,m,p如题中定义。
然后m行每行三个正整数t[k], w[k], x[k]描述第k只鼹鼠。
[输出文件]
只有一行一个整数为最大得分。
就加了一个条件p,只需在读入时将每个时间*p即可,因为移动速度*p,相当于出现速度/p
以t为纵轴,x为横轴,点i转移到j,i必须在坐标系中在j的左上方,将坐标系转移45°,(转移45°后,t=t-x;x=x+t(每一个都要除sqrt2 因此可以约掉))按t升序排列(双关键字ti=tj时xi<xj),以x维护一个决策集合,转移时,f[j]由决策集合中x[i]<x[j]的f[i]最大值转移,每产生一个决策f[j],就让它 进入该集合(按x[j]排列),可用树状数组维护(我用的是zkw线段树)
解释一下为什么要转移坐标。
转移坐标后,如果某点j t[j]>t[i],x[j]>x[i](均为转移后)那么j必然在过i点直线y=x+b1和y=-x+b2之上,那么原来坐标纵坐标之差必然大于横坐标之差,而纵坐标为时间,横坐标为距离,时间之差>距离之差 i肯定可以转移到j,也就是说,转移坐标是为了方便我们进行状态转移
const maxn=100000; type strike=record w,x,t:longint end; var a:array[1..maxn]of strike; f:array[1..maxn]of longint; max,ans,m1,n,m,p,maxx:longint; b:array[1..1310720]of longint; procedure qsort2(l,r:longint); var i,j:longint; c,x:strike; begin i:=l;j:=r;x:=a[(l+r) div 2]; repeat while (a[i].t<x.t)or((a[i].t=x.t)and(a[i].x<x.x)) do inc(i); while (x.t<a[j].t)or((a[j].t=x.t)and(x.x<a[j].x)) do dec(j); if not(i>j) then begin c:=a[i];a[i]:=a[j];a[j]:=c; inc(i);dec(j) end until i>j; if l<j then qsort2(l,j); if i<r then qsort2(i,r) end; function maxm(x,y:longint):longint; begin if x>y then exit(x) else exit(y) end; procedure change(x,y:longint); var i:longint; begin i:=x+m1; if y>b[i] then b[i]:=y else exit; i:=i>>1; while i<>0 do begin b[i]:=maxm(b[i<<1],b[i<<1+1]); i:=i>>1 end end; procedure question(l,r:longint); begin l:=l+m1;r:=r+m1; dec(l);inc(r); while not(l xor r=1) do begin if l and 1=0 then if b[l+1]>max then max:=b[l+1]; if r and 1=1 then if b[r-1]>max then max:=b[r-1]; l:=l>>1;r:=r>>1 end end; procedure origin; begin m1:=1; while m1<maxx+2 do m1:=m1<<1;m1:=m1-1; fillchar(b,sizeof(b),0); fillchar(f,sizeof(f),0); end; procedure init; var i,j,x1,t1:longint; begin readln(n,m,p);maxx:=0; for i:=1 to m do with a[i] do begin readln(t1,w,x1);t1:=t1*p; t:=(t1-x1);x:=(t1+x1); if x>maxx then maxx:=x end; origin; qsort2(1,m);ans:=0; for i:=1 to m do begin max:=0; question(1,a[i].x);f[i]:=max+a[i].w;change(a[i].x,f[i]); if f[i]>ans then ans:=f[i] end; writeln(ans); end; begin assign(input,'strick.in');reset(input); assign(output,'strick.out');rewrite(output); init; close(input);close(output) end.