题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006

每个右端点的左端点在一个区间内;用堆记录端点位置、可选区间,按价值排序;拿出一个后也许分裂成两个。

第一次写了ST表,写得巨复杂,记录向前/后的最小值和位置,还为了预处理,又记 2^j 走到哪;调了半天边界,最后发现是Lg写错了!至今仍不知那样写为什么会错……

看看别人的代码,原来不用记两个方向的,用的时候往前跳几步再用向后的就行!也不用记录最小值,只要记录位置就行了;也不用记录 to[ ][ ] ,只要从 i+2^j 有没有超过n就能判断边界。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
const int N=5e5+,Lm=;
int n,m,L,R,a[N],s[N],Lg[N],stp[N][Lm+],stn[N][Lm+],to[N][Lm+];
int idp[N][Lm+],idn[N][Lm+];
ll ans;
struct Node{
int ps,to,l,r,v;
Node(int p,int t,int l,int r,int v):ps(p),to(t),l(l),r(r),v(v) {}
bool operator< (const Node &b) const
{return v<b.v;}
};
priority_queue<Node> q;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='') ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return fx?ret:-ret;
}
void init()
{
/*
int i=1,cd=0,nxt;
for(;i<=n;i=nxt,cd++)
{
nxt=i<<1;
for(int j=i;j<nxt&&j<=n;j++) Lg[j]=cd;
}
i>>=1;
for(;i<=n;i++) Lg[i]=cd;
*/
for(int i=;i<=n;i++) Lg[i]=Lg[i>>]+; memset(to,0x3f,sizeof to);//
for(int i=;i<n;i++)
{
stp[i][]=s[i]; idp[i][]=i;
to[i][]=i-;
for(int j=,d;j<=Lm;j++)
{
d=to[i][j-];
if(d<||to[d][j-]>n)break;// >n!!! //if d<0
to[i][j]=to[d][j-];
if(stp[d][j-]<stp[i][j-])
{
stp[i][j]=stp[d][j-]; idp[i][j]=idp[d][j-];
}
else
{
stp[i][j]=stp[i][j-]; idp[i][j]=idp[i][j-];
}
}
}
memset(to,0x3f,sizeof to);
for(int i=n-;i>=;i--)
{
stn[i][]=s[i]; idn[i][]=i;
to[i][]=i+;
for(int j=,d;j<=Lm;j++)
{
d=to[i][j-];
if(to[d][j-]>n)break;
to[i][j]=to[d][j-];
if(stn[d][j-]<stn[i][j-])
{
stn[i][j]=stn[d][j-]; idn[i][j]=idn[d][j-];
}
else
{
stn[i][j]=stn[i][j-]; idn[i][j]=idn[i][j-];
}
}
}
}
int main()
{
n=rdn(); m=rdn(); L=rdn(); R=rdn();
for(int i=;i<=n;i++) a[i]=rdn(),s[i]=s[i-]+a[i];
init();
for(int i=,d,t;i<=n;i++)
{
int l=i-R,r=i-L;//not +1
if(r<) continue; l=max(l,);
t=Lg[r-l+];//not +1
d=(stp[r][t]<stn[l][t]?idp[r][t]:idn[l][t]);
q.push(Node(i,d,l,r,s[i]-s[d]));
} while(m--)
{
Node k=q.top(); q.pop(); ans+=k.v;
int l1=k.l,r1=k.to-, l2=k.to+,r2=k.r;
int t,d;
if(l1<=r1)
{
t=Lg[r1-l1+];
d=(stp[r1][t]<stn[l1][t]?idp[r1][t]:idn[l1][t]);
q.push(Node(k.ps,d,l1,r1,s[k.ps]-s[d]));
} if(l2<=r2)
{
t=Lg[r2-l2+];
d=(stp[r2][t]<stn[l2][t]?idp[r2][t]:idn[l2][t]);
q.push(Node(k.ps,d,l2,r2,s[k.ps]-s[d]));
}
}
printf("%lld\n",ans);
return ;
}

最新文章

  1. Selenium+python 配置
  2. 发现不错的cache系统Cache Manager Documentation
  3. MVC应用程序中管理(更新)上传的文件
  4. String、StringBuffer与StringBuilder的区别
  5. &lt;Error&gt;: CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
  6. js实现页面图片加载进度条
  7. html5实现烟花绽放效果
  8. STM32的FSMC总线复用调试笔记
  9. grails的controller和action那点事---远程调试groovy代码
  10. redhat初始化yum源,使用阿里云yum源
  11. Java企业微信开发_09_身份验证之移动端网页授权(有完整项目源码)
  12. 过滤html标签
  13. qt界面操作
  14. WINDOWS 2008Server 配置nginx 反向代理服务器 安装成服务
  15. css3中linear-gradient()的使用
  16. 鸟哥的 Linux 私房菜Shell Scripts篇(三)
  17. taro之React Native 端开发研究
  18. 关于java和c语言中,变量重名问题
  19. Fastjson, Gson, org.json.JSON三者对于JSONObject及JSONArray的判断
  20. Linux内存压力测试stressapptest

热门文章

  1. table 设置边框
  2. Android 学习之逐帧动画(Frame)
  3. redis 3.0.1 在CentOS上的安装
  4. android页面间传递对象
  5. POJ 1141 Brackets Sequence (区间DP)
  6. CentOS minimal 安装ssh 服务 和客户端
  7. python--软件规范和反射
  8. kubernetes调度之pod优先级和资源抢占
  9. 换站点Logo图片---轻开电子商务系统(企业入门级B2C站点)
  10. LeetCode215:Kth Largest Element in an Array