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

本来应该是可以用主席树,找区间最小值,取出来后再找那段区间的次小值......

但也可以只找最小值,取出来后把原来区间分裂成两个,继续找最小值,用ST表即可;

发现自己还没写过 ST 表囧...

思路同这里:https://www.cnblogs.com/CQzhangyu/p/7071394.html

自己写了半天,才10分...奋力改了改,那个 find 里面 r++ 而 l 不 ++ 的细节真奇妙...

然后就50分了...

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const xn=5e5+,inf=0x3f3f3f3f;
int n,k,L,R,t[xn],lg[xn],f[xn][],id[xn][],bin[],ans;
struct N{
int a,b,l,r;
bool operator < (const N &y) const
{return t[b]-t[a]<t[y.b]-t[y.a];}
};
priority_queue<N>q;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
void find(int l,int r,int &y)
{
int g=lg[r-l+];//
r++;//!!!!!
// printf("id[%d][%d]=%d\n",l,g,id[l][g]);
if(t[id[r][g]]<t[id[l+bin[g]][g]])y=id[r][g];
else y=id[l+bin[g]][g];
// printf("find(%d,%d)=%d\n",l,r,y);
}
int main()
{
n=rd(); k=rd(); L=rd(); R=rd();
bin[]=;
for(int i=,x;i<=n;i++)x=rd(),t[i]=t[i-]+x;
for(int i=,p,lst=;i<=n;i++)
{
if(i<lst*)lg[i]=lg[i-];
else lg[i]=lg[i-]+,lst*=,bin[lg[i]]=lst; id[i][]=i-; f[i][]=i-;
for(int j=;j<=;j++)
{
f[i][j]=f[f[i][j-]][j-];
if(t[id[i][j-]]<t[id[f[i][j-]][j-]])id[i][j]=id[i][j-];
else id[i][j]=id[f[i][j-]][j-];
} int l=max(i-R,),r=i-L,len=r-l+;
if(l>r)continue;
find(l,r,p); q.push((N){p,i,l,r});
// printf("ps:%d,%d\n",p,i);
}
int cnt=,p;
while(cnt<k)
{
int a=q.top().a,b=q.top().b,l=q.top().l,r=q.top().r; q.pop();
if(l<=a-)find(l,a-,p),q.push((N){p,b,l,a-})/*,printf("ps:%d,%d\n",p,b)*/;
if(a+<=r)find(a+,r,p),q.push((N){p,b,a+,r})/*,printf("ps:%d,%d\n",p,b)*/;
cnt++; ans+=t[b]-t[a];
// printf("a=%d b=%d\n",a,b);
}
printf("%d\n",ans);
return ;
}

最后发现把 ans 改成 long long 就A了!!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const xn=5e5+,inf=0x3f3f3f3f;
int n,k,L,R,t[xn],lg[xn],f[xn][],id[xn][],bin[];
long long ans;
struct N{
int a,b,l,r;
bool operator < (const N &y) const
{return t[b]-t[a]<t[y.b]-t[y.a];}
};
priority_queue<N>q;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
void find(int l,int r,int &y)
{
int g=lg[r-l+];//
r++;//!!!!!
// printf("id[%d][%d]=%d\n",l,g,id[l][g]);
if(t[id[r][g]]<t[id[l+bin[g]][g]])y=id[r][g];
else y=id[l+bin[g]][g];
// printf("find(%d,%d)=%d\n",l,r,y);
}
int main()
{
n=rd(); k=rd(); L=rd(); R=rd();
bin[]=;
for(int i=,x;i<=n;i++)x=rd(),t[i]=t[i-]+x;
for(int i=,p,lst=;i<=n;i++)
{
if(i<lst*)lg[i]=lg[i-];
else lg[i]=lg[i-]+,lst*=,bin[lg[i]]=lst; id[i][]=i-; f[i][]=i-;
for(int j=;j<=;j++)
{
f[i][j]=f[f[i][j-]][j-];
if(t[id[i][j-]]<t[id[f[i][j-]][j-]])id[i][j]=id[i][j-];
else id[i][j]=id[f[i][j-]][j-];
} int l=max(i-R,),r=i-L,len=r-l+;
if(l>r)continue;
find(l,r,p); q.push((N){p,i,l,r});
// printf("ps:%d,%d\n",p,i);
}
int cnt=,p;
while(cnt<k)
{
int a=q.top().a,b=q.top().b,l=q.top().l,r=q.top().r; q.pop();
if(l<=a-)find(l,a-,p),q.push((N){p,b,l,a-})/*,printf("ps:%d,%d\n",p,b)*/;
if(a+<=r)find(a+,r,p),q.push((N){p,b,a+,r})/*,printf("ps:%d,%d\n",p,b)*/;
cnt++; ans+=t[b]-t[a];
// printf("a=%d b=%d\n",a,b);
}
printf("%lld\n",ans);
return ;
}

A

但已经模仿了TJ啦...处理的时候果然要带上自己,不然各种不方便...

别忘了开 long long !因为是多段区间的和!

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const xn=5e5+,inf=0x3f3f3f3f;
int n,k,L,R,t[xn],lg[xn],id[xn][];
long long ans;
struct N{
int a,b,l,r;
bool operator < (const N &y) const
{return t[b]-t[a]<t[y.b]-t[y.a];}
};
priority_queue<N>q;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
int mn(int a,int b){return t[a]<t[b]?a:b;}
int find(int l,int r)
{
if(l>r)return -;
int g=lg[r-l+];
return mn(id[l][g],id[r-(<<g)+][g]);
}
int main()
{
n=rd(); k=rd(); L=rd(); R=rd();
for(int i=;i<=n;i++)lg[i]=lg[i>>]+;
for(int i=,x;i<=n;i++)x=rd(),t[i]=t[i-]+x,id[i][]=i;//
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++)//0 //-1
id[i][j]=mn(id[i][j-],id[i+(<<(j-))][j-]);
for(int i=L;i<=n;i++)q.push((N){find(max(i-R,),i-L),i,max(i-R,),i-L});
int cnt=,p;
while(cnt<k)
{
int a=q.top().a,b=q.top().b,l=q.top().l,r=q.top().r; q.pop();
cnt++; ans+=t[b]-t[a];
int c=find(l,a-),d=find(a+,r);
if(c!=-)q.push((N){c,b,l,a-});
if(d!=-)q.push((N){d,b,a+,r});
}
printf("%lld\n",ans);
return ;
}

bzoj 2006 超级钢琴 —— ST表的更多相关文章

  1. bzoj 2006 [NOI2010]超级钢琴——ST表+堆

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006 每个右端点的左端点在一个区间内:用堆记录端点位置.可选区间,按价值排序:拿出一个后也许 ...

  2. BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]

    题意: 一个序列,求k个不相同的长度属于\([L,R]\)的区间使得和最大 前缀和,对于每个r找最小的a[l] 然后我yy了一个可持久化线段树做法...也许会T 实际上主席树就可以了,区间k小值 然后 ...

  3. BZOJ 2006: [NOI2010]超级钢琴 ST表+堆

    开始想到了一个二分+主席树的 $O(n\log^2 n)$ 的做法. 能过,但是太无脑了. 看了一下题解,有一个 ST 表+堆的优美解法. 你发现肯定是选取前 k 大最优. 然后第一次选的话直接选固定 ...

  4. 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2473  Solved: 1211[Submit][Statu ...

  5. [BZOJ2006][NOI2010]超级钢琴(ST表+堆)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3679  Solved: 1828[Submit][Statu ...

  6. 【BZOJ2006】[NOI2010]超级钢琴 ST表+堆

    [BZOJ2006][NOI2010]超级钢琴 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以 ...

  7. [BZOJ 2006] 超级钢琴

    Link: https://www.lydsy.com/JudgeOnline/problem.php?id=2006 Algorithm: 对于此类区间最值类问题,我们可以通过控制一端不变来寻找当前 ...

  8. BZOJ 2006 超级钢琴(划分树+优先队列)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2006 题意: 给出一个数列A,L,R,构造出一个新的集合,集合中的数字为A中任意连续t( ...

  9. BZOJ 2006 超级钢琴(堆+主席树)

    很好的一道题. 题意:给出长度为n的数列,选择k个互不相同的区间,满足每个区间长度在[L,R]内,求所有选择的区间和的总和最大是多少.(n,k<=5e5). 首先将区间和转化为前缀和之差,那么我 ...

随机推荐

  1. PTA 04-树5 Root of AVL Tree (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/668 5-6 Root of AVL Tree   (25分) An AVL tree ...

  2. DBCA建库出错ORA-00600: internal error code, arguments

    正常步骤安装完成Oralce,通过dbca建库,报错如下图所示: Oracle安装日志中报错如下: [Thread-40] [ 1999-12-15 12:23:54.055 CST ] [Basic ...

  3. 【ZJOI2017 Round1练习&BZOJ4767】D1T3 两双手(排列组合,DP)

    题意: 100%的数据:|Ax|,|Ay|,|Bx|,|By| <= 500, 0 <= n,Ex,Ey <= 500 思路:听说这是一道原题 只能往右或者下走一步且有禁止点的简化版 ...

  4. jquery的ajax提交时“加载中”提示的处理方法

    方法1:使用ajaxStart方法定义一个全局的“加载中...”提示 $(function(){    $("#loading").ajaxStart(function(){    ...

  5. 洛谷——P1596 [USACO10OCT]湖计数Lake Counting

    P1596 [USACO10OCT]湖计数Lake Counting 题目描述 Due to recent rains, water has pooled in various places in F ...

  6. Netflix是什么,与Spring Cloud有什么关系

    说明:以下总结的观点不一定准确,但是是最好理解的. 1.首先,Netflix是一家做视频的网站,可以这么说该网站上的美剧应该是最火的. 2.Netflix是一家没有CTO的公司,正是这样的组织架构能使 ...

  7. IntelliJ IDEA14.0.3+Maven+SpringMVC+Spring+Hibernate光速构建Java权限管理系统(三)

    注册登录 --利用简单的编写注册登录系统来打通从前端到后台的数据传输路径. 一.建立数据库.基本表 基本环境:mysql5,7.Navicat for MySQL11.0.9企业版. 我们在本地MyS ...

  8. django 简易博客开发 3 静态文件、from 应用与自定义

    首先还是贴一下源代码地址  https://github.com/goodspeedcheng/sblog 上一篇博客我们介绍了 django 如何在views中使用templates以及一些常用的数 ...

  9. [TypeScript] Query Properties with keyof and Lookup Types in TypeScript

    The keyof operator produces a union type of all known, public property names of a given type. You ca ...

  10. 积跬步,聚小流------ps有用小技巧,改变png图标颜色

    *  实现效果: 原图:  改动后: *  实现目的: 满足为实现不同界面色彩搭配改动png图标的颜色 *  实现方法: 1.打开Photoshop工具,导入须要进行改动的png图标: 2.对导入的图 ...