B_1168 @ 2020-04-26 01:03:38
本蒟蒻实在不会单调队列……大数据不知为何从后几位开始WA,求助qwq
#include<bits/stdc++.h>
using namespace std;
const int maxn=100001;
int n,k,be[maxn],len;
long long tot,dp[maxn],val[maxn];
void upd(int pos,long long num){//单点更新lazytag最小值
dp[pos]+=num;
val[be[pos]]=min(val[be[pos]],dp[pos]);
}
long long query(int from,int to){//区间查询
long long cnt=0x7f7f7f7f;
for(int i=from;i<=min(to,be[from]*len);i++) cnt=min(cnt,dp[i]);
if(be[from]!=be[to]){
for(int i=(be[to]-1)*len+1;i<=to;i++) cnt=min(cnt,dp[i]);
}
for(int i=be[from]+1;i<=be[to]-1;i++) cnt=min(cnt,val[i]);
return cnt;
}
int main(){
freopen("P2627_2.in","r",stdin);
freopen("P2627_2_2.out","w",stdout);
scanf("%d%d",&n,&k);
memset(val,0x7f7f7f,sizeof(val));
len=sqrt(n);
for(long long i=1;i<=n;i++)be[i]=(i-1)/len+1;
for(int i=1;i<=n;i++){
scanf("%d",&dp[i]);
tot+=dp[i];
val[be[i]]=min(val[be[i]],dp[i]);
}
for(int i=1;i<=n+1;i++){//以下注释部分可以理解为朴素版转移方程
/* long long temp=1<<30;
for(int j=i-k-1;j<i;j++){
temp=min(temp,dp[j]);
}
dp[i]+=temp;*/
upd(i,query(max(0,i-k-1),i-1));//i-K-1≤j<i
}
for(int i=1;i<=n+1;i++) printf("%lld ",dp[i]);
// printf("%lld\n",tot-dp[n+1]);
}
by metaphysis @ 2020-04-27 23:34:33
@B_1168
如果您对单调队列优化不是很熟悉,您可以参考我写的书 《C++,挑战编程——程序设计竞赛进阶训练指南》,书中第11章“动态规划”的第11.9.4小节“单调队列优化”有简要的介绍,您可以参考。
下面来解答您的问题。您用了分块查找来提高查询效率,但是初始化发生错误,只要稍作修改即可Accepted,原因请您自己再想想。
提示:
val[be[i]]=min(val[be[i]],dp[i]);