BZOJ4850: [Jsoi2016]灯塔
2017-06-06 18:22
211 查看
BZOJ4850
很容易发现sqrt(|i−j|)很多情况下都是相等的。
那么就可以考虑分块。(题目应该是hj≤hi+p−sqrt(|i−j|))
当sqrt(|i−j|)=x时,令Mx为所有满足sqrt(|i−j|)=x的j中,最大的hj值。
那么p>=Mx+sqrt(|i−j|)−hi
一开始直接将sqrt(|i−j|)=x四舍五入了。。显然错了。应该向上取整。
然后发现长度为1时,x=1,长度为2,3,4时,x=2,长度为5,6,7,8,9时,x=3……
那么(i−1)2+1到i2的sqrt(|i−j|)是相等的。就可以分块了。
对于每一块,用RMQ求出块内最大值,对于每一块,求出最大值即可。Ansi=Max(Mx+x−hi)
复杂度O(NN−−√)。只要打的不算太丑都能水过去。。QAQdsy垫底1.15s噢不能用线段树。。加个log就跑不过去了。
至于正解。。决策单调性整体二分什么的。。反正我不会
很容易发现sqrt(|i−j|)很多情况下都是相等的。
那么就可以考虑分块。(题目应该是hj≤hi+p−sqrt(|i−j|))
当sqrt(|i−j|)=x时,令Mx为所有满足sqrt(|i−j|)=x的j中,最大的hj值。
那么p>=Mx+sqrt(|i−j|)−hi
一开始直接将sqrt(|i−j|)=x四舍五入了。。显然错了。应该向上取整。
然后发现长度为1时,x=1,长度为2,3,4时,x=2,长度为5,6,7,8,9时,x=3……
那么(i−1)2+1到i2的sqrt(|i−j|)是相等的。就可以分块了。
对于每一块,用RMQ求出块内最大值,对于每一块,求出最大值即可。Ansi=Max(Mx+x−hi)
复杂度O(NN−−√)。只要打的不算太丑都能水过去。。QAQdsy垫底1.15s噢不能用线段树。。加个log就跑不过去了。
至于正解。。决策单调性整体二分什么的。。反正我不会
【代码】
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #define N 100005 #define mod 1000000007 #define INF 0x7fffffff using namespace std; typedef long long ll; ll read() { ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } int n,sum; int h ,DP [30],Bit ; void RMQ() { int temp=(int)(log((double)n)/log(2.0)); for(register int i=1;i<=n;i++) Bit[i]=(int)(log((double)i)/log(2.0)); for(register int i=1;i<=n;i++) DP[i][0]=h[i]; for(register int j=1;j<=temp;j++) for(register int i=1;i<=n;i++) if(i+(1<<j)<=n) DP[i][j]=max(DP[i][j-1],DP[i+(1<<(j-1))][j-1]); } int Query(int L,int R) { int k=Bit[R-L+1]; return max(DP[L][k],DP[R-(1<<k)+1][k]); } void Solve(int x) { int i=1,j=x-1,ans=0; while(1) { int len=i*i-(i-1)*(i-1); int jj=j-len+1;jj=max(jj,1); if(jj>j) break; int mx=Query(jj,j); ans=max(ans,mx-h[x]+i); if(jj==1) break;j=jj-1;i++; } i=1,j=x+1; while(1) { int len=i*i-(i-1)*(i-1); int jj=j+len-1;jj=min(jj,n); if(jj<j) break; int mx=Query(j,jj); ans=max(ans,mx-h[x]+i); if(jj==n) break;j=jj+1;i++; } printf("%d\n",ans); } int main() { n=read(); for(register int i=1;i<=n;i++) h[i]=read(); RMQ(); for(register int i=1;i<=n;i++) Solve(i); return 0; }
相关文章推荐
- [bzoj4850][Jsoi2016]灯塔
- [二分+DFS序上DP]BZOJ 4753—— [Jsoi2016]最佳团体
- BZOJ4755: [JSOI2016]扭动的回文串——题解
- BZOJ.4753.[JSOI2016]最佳团体(01分数规划 树形背包DP)
- BZOJ4755 [Jsoi2016]扭动的回文串
- 【bzoj4753】[Jsoi2016]最佳团体 分数规划+树形背包dp
- bzoj4753: [Jsoi2016]最佳团体(分数规划+树形依赖背包)
- BZOJ4850 [Jsoi2016]灯塔
- bzoj4753[JSOI2016]最佳团体
- 【BZOJ4753】【JSOI2016】最佳团体(树形dp+二分)
- bzoj4755: [Jsoi2016]扭动的回文串 manacher+二分+Hash
- BZOJ 4753: [Jsoi2016]最佳团体
- BZOJ 4753 [Jsoi2016]最佳团体 ——01分数规划 树形DP
- BZOJ 4753 [Jsoi2016]最佳团体 | 树上背包 分数规划
- BZOJ 4753: [Jsoi2016]最佳团体 树形背包 01分数规划
- 【BZOJ4852】【JSOI2016】炸弹攻击
- [bzoj4753][Jsoi2016]最佳团体 树上背包+二分
- bzoj 4753: [Jsoi2016]最佳团体 二分答案+树形dp
- BZOJ_4753_[Jsoi2016]最佳团体_树形背包+01分数规划
- 【BZOJ】4753: [Jsoi2016]最佳团体 01分数规划+树上背包