JZOJ 4687 奇袭【NOIP2016提高A组8.12】
来源:互联网 发布:伊朗 知乎 编辑:程序博客网 时间:2024/05/22 06:42
奇袭
题目大意
给出一张
如果一个
数据范围
对于30%的数据,
对于60%的数据,
对于100%的数据,
题解
30分
定义:第
首先想到的肯定就是用二维前缀和来做,枚举右下角的位置,再枚举
但如果这样做的话,时间复杂度就是
60分
我们优化一下,尝试用
按照
我们发现,如果在一段长度为
枚举区间右边界,从右往左枚举左边界的同时用
100分
至于100分的正解,我们需要从60分的优化而来。
我们使用分治算法。
假设我们需要求区间(
我们对这种 区间进行分类讨论。
<1>最大值、最小值在
<2>最大值、最小值在
在进行讨论之前,我们先定义四个数组:
mil[i]=min(y[i],y[i+1]……,y[m-1],y[m]) =min(y[i],mil[i+1])(L<=i<=m)
mal[i]=max(y[i],y[i+1]……,y[m-1],y[m]) =max(y[i],mal[i+1])(L<=i<=m)
mir[i]=min(y[m+1],y[m+2],……y[r-1],y[r]) =min(y[i],mir[i-1])(m < i<=R)
mar[i]=max(y[m+1],y[m+2],……y[r-1],y[r]) =max(y[i],mar[i-1])(m < i<=R)
我们先考虑第一种情况 最大值、最小值在
Yi 的最大值-Yi 的最小值=len ,即mal[i ]-mil[i ]=j -i
我们发现这个式子只有
求出
最大值和最小值在
第一种情况讨论完了,我们就讨论第二种:最大值、最小值在
若一个”
Yi 的最大值-Yi 的最小值=len
即mar[j]-mil[i]=j-i(j为区间右边界,i为区间左边界)
移项,得
即mar[j]-j=mil[i]-i(j为区间右边界,i为区间左边界)
我们开一个桶,
有了这个定义,就可以做了。
我们枚举
我们让
再让
“
mal[j]-mir[i]=i-j(j为区间左边界,i为区间右边界)。
上面一堆复杂的操作搞完以后,就可以分成两段继续统计答案了。时间复杂度
Code(Pascal)
var t:array[-100000..100000] of longint; x,y,kkk,uuu,ppp:array[0..60000] of longint; n,j,m,k,l,r,i,o,p,ans:longint; function max(a,b:longint):longint; begin if a>b then exit(a) else exit(b); end;function min(a,b:longint):longint; begin if a<b then exit(a) else exit(b); end;procedure ef(l,r:longint); var i,j,m,tt,zx,zd,r1,r2:longint; begin if l=r then exit; m:=(l+r) div 2; zx:=maxlongint; zd:=0; for i:=m downto l do begin zx:=min(zx,y[i]); zd:=max(zd,y[i]); kkk[i]:=zd; uuu[i]:=zx; end; zx:=maxlongint; zd:=0; for i:=m+1 to r do begin zx:=min(zx,y[i]); zd:=max(zd,y[i]); kkk[i]:=zd; uuu[i]:=zx; end; for i:=l to m do begin tt:=kkk[i]-uuu[i]+i; if tt<=r then if (tt>m) and (kkk[i]>kkk[tt]) and (uuu[i]<uuu[tt]) then inc(ans); end; for i:=m+1 to r do begin tt:=i-(kkk[i]-uuu[i]); if tt>=l then if (tt<=m) and (kkk[i]>kkk[tt]) and (uuu[i]<uuu[tt]) then inc(ans); end; r2:=m; r1:=m+1; for i:=m+1 to r do begin zd:=kkk[i]; zx:=uuu[i]; while (zx<uuu[r2]) and (r2>=l) do begin dec(t[uuu[r2]-r2]); dec(r2); end; if r2<l then break; while (zd>kkk[r1-1]) and (r1>l) do begin dec(r1); inc(t[uuu[r1]-r1]); end; if r1<=r2 then ans:=ans+t[zd-i]; end; for i:=m downto l do t[uuu[i]-i]:=0; r1:=m+1; r2:=m; for i:=m downto l do begin zd:=kkk[i]; zx:=uuu[i]; while (zx<uuu[r1]) and (r1<=r) do begin dec(t[uuu[r1]+r1]); inc(r1); end; if r1>r then break; while (zd>kkk[r2+1]) and (r2<r) do begin inc(r2); inc(t[uuu[r2]+r2]); end; if r2>=r1 then ans:=ans+t[zd+i]; end; for i:=m+1 to r do t[uuu[i]+i]:=0; for i:=l to r do begin uuu[i]:=0; kkk[i]:=0; end; ef(l,m); ef(m+1,r); end;begin readln(n); for i:=1 to n do begin readln(x[i],y[i]); ppp[x[i]]:=y[i]; end; for i:=1 to n do y[i]:=ppp[i]; ans:=n; ef(1,n); writeln(ans);end.
- JZOJ 4687 奇袭【NOIP2016提高A组8.12】
- 【NOIP2016提高A组8.12】奇袭
- 【NOIP2016提高A组8.12】奇袭
- 4687. 【NOIP2016提高A组8.12】奇袭
- JZOJ.4685. 【NOIP2016提高A组8.12】礼物
- JZOJ.4686. 【NOIP2016提高A组8.12】通讯
- JZOJ 4685 礼物【NOIP2016提高A组8.12】
- JZOJ 4686 通讯【NOIP2016提高A组8.12】
- 【JZOJ 4687】奇袭
- JZOJ 4637 大鱼海棠【NOIP2016提高组A组7.16】
- JZOJ 4639 Angel Beats!【NOIP2016提高组A组7.16】
- JZOJ 4628 立方体【NOIP2016提高A组模拟7.15】
- JZOJ 4629 修路【NOIP2016提高A组模拟7.15】
- JZOJ 4630 计数【NOIP2016提高A组模拟7.15】
- JZOJ 4603 颜料大乱斗【NOIP2016提高A组模拟7.15】
- JZOJ 4647 寻找 【NOIP2016提高A组模拟7.17】
- JZOJ.4678【NOIP2016提高A组8.11】 钱仓
- JZOJ 4679 种树【NOIP2016提高A组8.11】
- 1021. Deepest Root (25)
- TreeSet中自定义排序的两种方法
- HDU1513:Palindrome
- 关于UPnP Device Architecture 2.0的阅读笔记(六)
- JAVA学习代码——回音壁
- JZOJ 4687 奇袭【NOIP2016提高A组8.12】
- 贡献思路题目集合
- android5.0与6.0 sd卡挂载
- Fragment 布局属性 tools:layout 作用
- JAVA学习代码——进制转换
- jquery使用ajax提交表单
- Java经典实例代码
- POJ 2155 Matrix(二维树状数组)
- 夏令营day9总结