2017.2.12【初中部 GDKOI】模拟赛B组 T4:pot
2017-02-24 19:39
288 查看
pot
Description
这个假期,小h在自家院子里种了许多花,它们围成了一个圈,从1..n编号(n<=100000),小h 对每盆花都有一个喜好值xi,(-1000<=xi<=1000),小h现在觉得这样一成不变很枯燥,于是他做了m(m<=100000)个改动,每次把第ki盘花改成喜好值为di的花,然后小h要你告诉他,在这个花圈中,连续的最大喜好值是多少。
Input
第一行,n,花盆的数量
第二行,n个数,表示对于每盆花的喜好值。
第三行:m, 改动的次数
以下m行,每行两个数ki 和di 。
Output
M行,每一行对应一个更改,表示连续的最大喜好值,且不能整圈都选。(注意:是在圈上找)
Sample Input
5
3 -2 1 2 -5
4
2 -2
5 -5
2 -4
5 -1
Sample Output
4
4
3
5
题解:
对于20分,当然是用一个暴力过去啦~~~
对于30分,用O(nm)的动态规划,再加上卡常数就好了。
对于100分,此题满分做法涉及到线段树,不懂的可以去了解一下。
本题题意是数形成一个环状,又说了不可以全部数选择。那么,我们只需要求出1到n内最大的子区间和;从两边开始选的最大子区间和;1到n内最小的子区间和;从两边开始选的最小子区间和。因为我们要求出这样的东东:
那么,最优答案就是sum(表示数环的总和)-min或max。这时,我们用线段树来做这些操作,然后大体细节就好好看题,笔玩一下就可以推出线段树维护的规律。
来给个伪程序来维护max和min的操作:
解答问题1:lgss和rgss有何用?答:这个可以时刻维护max的求值,具体维护法笔玩一下,这里不多说。(因为要说明就要画图)
解答问题2:如何判断有没有全部选。答:这是废话,只需要判断max值与sum值相不相等。
解答问题3:为什么sum要在树内做。答:这可以更好地去维护maxlgss、maxrgss、minlgss、minrgss的操作,当然时间会更快的问题我就不确定了。
解答问题4:线段树怎么做。答:自己研究。
标程:
Description
这个假期,小h在自家院子里种了许多花,它们围成了一个圈,从1..n编号(n<=100000),小h 对每盆花都有一个喜好值xi,(-1000<=xi<=1000),小h现在觉得这样一成不变很枯燥,于是他做了m(m<=100000)个改动,每次把第ki盘花改成喜好值为di的花,然后小h要你告诉他,在这个花圈中,连续的最大喜好值是多少。
Input
第一行,n,花盆的数量
第二行,n个数,表示对于每盆花的喜好值。
第三行:m, 改动的次数
以下m行,每行两个数ki 和di 。
Output
M行,每一行对应一个更改,表示连续的最大喜好值,且不能整圈都选。(注意:是在圈上找)
Sample Input
5
3 -2 1 2 -5
4
2 -2
5 -5
2 -4
5 -1
Sample Output
4
4
3
5
题解:
对于20分,当然是用一个暴力过去啦~~~
对于30分,用O(nm)的动态规划,再加上卡常数就好了。
对于100分,此题满分做法涉及到线段树,不懂的可以去了解一下。
本题题意是数形成一个环状,又说了不可以全部数选择。那么,我们只需要求出1到n内最大的子区间和;从两边开始选的最大子区间和;1到n内最小的子区间和;从两边开始选的最小子区间和。因为我们要求出这样的东东:
那么,最优答案就是sum(表示数环的总和)-min或max。这时,我们用线段树来做这些操作,然后大体细节就好好看题,笔玩一下就可以推出线段树维护的规律。
来给个伪程序来维护max和min的操作:
{v为当前树的深度} tree[v].sum:=tree[v*2].sum+tree[v*2+1].sum;{求sum值} tree[v].max:=max(max(tree[v*2].max,tree[v*2+1].max),tree[v*2].rgss+tree[v*2+1].lgss);{求max的值} tree[v].lgss:=tree[v*2].lgss;{左边的maxlgss值} tree[v].rgss:=tree[v*2+1].rgss;{右边的maxrgss值} tree[v].min:=min(min(tree[v*2].min,tree[v*2+1].min),tree[v*2].mrgss+tree[v*2+1].mlgss);{求min的值} tree[v].mlgss:=tree[v*2].mlgss{求左边的minlgss值}; tree[v].mrgss:=tree[v*2+1].mrgss{求右边的minrgss值}; if(tree[v*2].lgss<tree[v*2].sum+tree[v*2+1].lgss) then begin tree[v].l 4000 gss:=tree[v*2].sum+tree[v*2+1].lgss; end; if(tree[v*2+1].rgss<tree[v*2+1].sum+tree[v*2].rgss) then begin tree[v].rgss:=tree[v*2+1].sum+tree[v*2].rgss; end; if(tree[v*2].mlgss>tree[v*2].sum+tree[v*2+1].mlgss) then begin tree[v].mlgss:=tree[v*2].sum+tree[v*2+1].mlgss; end; if(tree[v*2+1].mrgss>tree[v*2+1].sum+tree[v*2].mrgss) then begin tree[v].mrgss:=tree[v*2+1].sum+tree[v*2].mrgss; end;
解答问题1:lgss和rgss有何用?答:这个可以时刻维护max的求值,具体维护法笔玩一下,这里不多说。(因为要说明就要画图)
解答问题2:如何判断有没有全部选。答:这是废话,只需要判断max值与sum值相不相等。
解答问题3:为什么sum要在树内做。答:这可以更好地去维护maxlgss、maxrgss、minlgss、minrgss的操作,当然时间会更快的问题我就不确定了。
解答问题4:线段树怎么做。答:自己研究。
标程:
type new=record max:longint; lgss:longint; rgss:longint; min:longint; mlgss:longint; mrgss:longint; sum:longint; end; var i,j,k,l,n,m,t,r,x,gb,ans:longint; a:array[0..1000000] of longint; tree:array[0..1000000] of new; bz:boolean; function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end; function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; procedure maketree(x,st,en:longint); var m:longint; begin tree[x].max:=-50001; tree[x].min:=50001; tree[x].lgss:=-50001; tree[x].rgss:=-50001; tree[x].mlgss:=50001; tree[x].mrgss:=-50001; if st=en then begin exit; end else begin m:=(st+en) div 2; maketree(x+x,st,m); maketree(x+x+1,m+1,en); end; end; procedure changenumber(v,x,l,r:longint); var i,j,mid:longint; begin if l=r then begin tree[v].max:=gb; tree[v].min:=gb; tree[v].lgss:=gb; tree[v].rgss:=gb; tree[v].mlgss:=gb; tree[v].mrgss:=gb; tree[v].sum:=gb; exit; end; mid:=(r+l) div 2; if x>mid then begin changenumber(v*2+1,x,mid+1,r); end else if x<=mid then begin changenumber(v*2,x,l,mid); end; tree[v].sum:=tree[v*2].sum+tree[v*2+1].sum; tree[v].max:=max(max(tree[v*2].max,tree[v*2+1].max),tree[v*2].rgss+tree[v*2+1].lgss); tree[v].lgss:=tree[v*2].lgss; tree[v].rgss:=tree[v*2+1].rgss; tree[v].min:=min(min(tree[v*2].min,tree[v*2+1].min),tree[v*2].mrgss+tree[v*2+1].mlgss); tree[v].mlgss:=tree[v*2].mlgss; tree[v].mrgss:=tree[v*2+1].mrgss; if(tree[v*2].lgss<tree[v*2].sum+tree[v*2+1].lgss) then begin tree[v].lgss:=tree[v*2].sum+tree[v*2+1].lgss; end; if(tree[v*2+1].rgss<tree[v*2+1].sum+tree[v*2].rgss) then begin tree[v].rgss:=tree[v*2+1].sum+tree[v*2].rgss; end; if(tree[v*2].mlgss>tree[v*2].sum+tree[v*2+1].mlgss) then begin tree[v].mlgss:=tree[v*2].sum+tree[v*2+1].mlgss; end; if(tree[v*2+1].mrgss>tree[v*2+1].sum+tree[v*2].mrgss) then begin tree[v].mrgss:=tree[v*2+1].sum+tree[v*2].mrgss; end; end; begin //assign(input,'xds.in');reset(input); //assign(output,'xds.out');rewrite(output); readln(n); maketree(1,1,n); for i:=1 to n do begin read(a[i]); end; for i:=1 to n do begin gb:=a[i]; changenumber(1,i,1,n); end; readln(m); for k:=1 to m do begin readln(l,r); gb:=r; changenumber(1,l,1,n); if(tree[1].max=tree[1].sum) then begin writeln(tree[1].max-tree[1].min); continue; end; if(tree[1].max>=tree[1].sum-tree[1].min) then begin writeln(tree[1].max); continue; end; if(tree[1].max<tree[1].sum-tree[1].min) then begin writeln(tree[1].sum-tree[1].min); end; end; end.
相关文章推荐
- 2017.2.11【初中部 GDKOI】模拟赛B组 T4:摧毁巴士站
- 2017.2.12【初中部 GDKOI】模拟赛B组 T2:宿敌
- 2017.2.12【初中部 GDKOI】模拟赛B组 T1:圆盘染色
- 2017.2.12【初中部 GDKOI】模拟赛B组 T3:seek
- 2017.2.12【初中部 GDKOI】模拟赛B组
- 2017.1.12【初中部 GDKOI】模拟赛B组
- 2017.1.14【初中部 GDKOI】模拟赛B组
- 2017.1.19【初中部 GDKOI】模拟赛B组
- 2017.2.10【初中部 GDKOI】模拟赛B组 方格游戏(game) 题解
- 2017.2.11【初中部 GDKOI】模拟赛B组题解
- 2017.2.11【初中部 GDKOI】模拟赛B组 T2:软件公司
- 2016.12.24【初中部 GDKOI 】模拟赛B组
- 2016.12.30【初中部 GDKOI】模拟赛B组
- 2017.1.13【初中部 GDKOI】模拟赛B组
- 2017.1.14【初中部 GDKOI】模拟赛B组 Mooo Moo 题解
- 2017.1.17【初中部 GDKOI】模拟赛B组 穿越泥地 题解
- 2017.1.17【初中部 GDKOI】模拟赛B组
- 2017.1.20【初中部 GDKOI】模拟赛B组
- 2017.2.10【初中部 GDKOI】模拟赛B组 粉刷(paint) 题解
- 2017.2.11【初中部 GDKOI】模拟赛B组题解