BZOJ 2006: [NOI2010]超级钢琴
2017-08-29 21:02
337 查看
Orz zzk
最直接的想法是找出所有不同的长度在[L,R]的子段然后选最大的k个加到答案中
但是太暴力没前途啊
zzk教会我:
首先构造前缀和数组pre
定义一个三元组MAX(i,L,R)表示以i为右端点且左端点在[L,R]之间的使pre[i]-pre[t-1]最大的值
(等价于[L,R]中使pre[t-1]最小的值) 其中(L<=t<=R)
显然ans就是k个最大的这样的三元组的值的和
可以用ST表+堆
首先枚举i,用ST表找到最小的pre[t] (作为初始状态) 放入一个堆中
然后进行k次查找:每次找到堆顶计入ans,然后因为需要选出的子段各不相同,把(i,L,R)拆成(i,L,t-1)和(i,t+1,r)放入堆中
最直接的想法是找出所有不同的长度在[L,R]的子段然后选最大的k个加到答案中
但是太暴力没前途啊
zzk教会我:
首先构造前缀和数组pre
定义一个三元组MAX(i,L,R)表示以i为右端点且左端点在[L,R]之间的使pre[i]-pre[t-1]最大的值
(等价于[L,R]中使pre[t-1]最小的值) 其中(L<=t<=R)
显然ans就是k个最大的这样的三元组的值的和
可以用ST表+堆
首先枚举i,用ST表找到最小的pre[t] (作为初始状态) 放入一个堆中
然后进行k次查找:每次找到堆顶计入ans,然后因为需要选出的子段各不相同,把(i,L,R)拆成(i,L,t-1)和(i,t+1,r)放入堆中
#include<cstdio> #include<algorithm> #include<queue> #define N 500005 #define RG register #define LL long long #define maxlog 20 using namespace std; inline int read() { int a=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){a=a*10+c-'0';c=getchar();} return a*f; } int n,L,R,k; LL ans; int pre ,Log[N+5],ST [maxlog+5]; struct node { int i,l,r,t; node(int a,int b,int c,int d) {i=a;l=b;r=c;t=d;} bool operator < (const node &c) const { return pre[i]-pre[t-1]<pre[c.i]-pre[c.t-1]; } }; int MIN(int a,int b){return pre[a-1]<pre[b-1]?a:b;} int query(int x,int y) { int p=Log[y-x+1]; return MIN(ST[x][p],ST[y-(1<<p)+1][p]); } priority_queue<node> heap; int main() { n=read(),k=read(),L=read(),R=read(); RG int i,j; for(i=1;i<=n;++i) pre[i]=read()+pre[i-1],ST[i][0]=i; for(i=2;i<=n;++i) Log[i]=Log[i>>1]+1; for(j=1;(1<<j)<=n;++j) for(i=1;i<=n-(1<<j)+1;++i) ST[i][j]=MIN(ST[i][j-1],ST[i+(1<<j-1)][j-1]); for(i=L;i<=n;++i) { int l=max(i-R+1,1),r=i-L+1; heap.push(node(i,l,r,query(l,r))); } ans=0; for(i=1;i<=k;++i) { node x=heap.top();heap.pop(); ans+=1ll*(pre[x.i]-pre[x.t-1]); if(x.t>x.l) heap.push(node(x.i,x.l,x.t-1,query(x.l,x.t-1))); if(x.t<x.r) heap.push(node(x.i,x.t+1,x.r,query(x.t+1,x.r))); } printf("%lld\n",ans); return 0; }
相关文章推荐
- bzoj2006 [NOI2010]超级钢琴
- 【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)
- BZOJ 2006: [NOI2010]超级钢琴 RMQ 优先队列
- bzoj2006 [NOI2010]超级钢琴
- BZOJ 2006 [NOI2010]超级钢琴 主席树+堆
- 【BZOJ2006】【NOI2010】超级钢琴(堆)
- bzoj2006 [NOI2010]超级钢琴 [优先队列|RMQ]
- NOI2010...BZOJ2006 超级钢琴 贪心
- [BZOJ2006][NOI2010]超级钢琴
- 【bzoj2006】【NOI2010】【超级钢琴】
- [NOI2010][bzoj2006] 超级钢琴 [主席树/ST表+堆]
- BZOJ2006: [NOI2010]超级钢琴
- BZOJ2006: [NOI2010]超级钢琴
- bzoj 2006: [NOI2010]超级钢琴 可持久化线段树+优先队列
- 【bzoj2006】[NOI2010]超级钢琴 堆+st表
- BZOJ 2006 NOI2010 超级钢琴 划分树+堆
- bzoj 2006 [NOI2010]超级钢琴 二分答案 可持久化线段树
- NOI 2010 COGS 468 BZOJ 2006 超级钢琴 RMQ 堆 => 乱搞 (脑洞要大大的)
- 【NOI2010】【BZOJ2006】超级钢琴
- BZOJ2006 [NOI2010]超级钢琴