【NOI2010】【BZOJ2006】超级钢琴
Description 3 2 ⑹ 8
Sample Output
【样例说明】
音符1 ~ 2,美好度为3 + 2 = 5
HINT数据范围及提示 Data Size & Hint 所有数据满足:⑴000 ≤ Ai ≤ 1000,1 ≤ L ≤ R ≤ n且保证1定存在满足要求的乐曲。 Source Day1
斟酌用3元组[l,r1,r2]表示在所有区间[l,r1],[l,r1+1],…,r2]这些区间里区间和最大值的最大值,并记录取到最大值的位置.线段树保护1个前缀和加上那个位置就行.
#include #include #include #include #include #include #define MAXN 500100 #define GET (ch>=0&&ch<=9) #define lchild rt<<1,l,mid #define rchild rt<<1|1,mid+1,r #define ln rt<<1 #define rn rt<<1|1 #define LL long long using namespace std;
LL n,_l,_r;
LL ans,a[MAXN]; struct seg
{ int l,r;
LL maxn,pos;
}tree[MAXN<<2]; struct node
{ int i,r,maxn,pos;
inline bool operator <(const node& a)const { return maxnvoid push_up(int rt)
{ if (tree[ln].maxn<=tree[rn].maxn) tree[rt].maxn=tree[rn].maxn,tree[rt].pos=tree[rn].pos; else tree[rt].maxn=tree[ln].maxn,tree[rt].pos=tree[ln].pos;
} void build(int rt=1,int l=1,int r=n)
{
tree[rt].l=l;tree[rt].r=r;int mid=l+r>>1; if (l==r) {tree[rt].maxn=a[l];tree[rt].pos=l;return;}
build(lchild);build(rchild);push_up(rt);
}
seg query(int rt,int l,int r)
{ int L=tree[rt].l,R=tree[rt].r,mid=L+R>>1;seg ret;ret.maxn=ret.pos=0; if (l<=L&&R<=r) return tree[rt]; if (r<=mid) return query(ln,r); if (l>mid) return query(rn,r);
seg a=query(ln,mid),b=query(rn,mid+1,r);ret=a.maxn>b.maxn?a:b; return ret;
} void in(long long &x)
{
x=0;char ch=getchar();int flag=1; while (!GET) flag=ch==-?-1:1,ch=getchar(); while (GET) x=x*10+ch-0,ch=getchar();x*=flag;
} int main()
{ in(n);in(k);in(_l);in(_r);node tmp,temp;seg t; for (int i=1;i<=n;i++) in(a[i]),a[i]=a[i-1]+a[i];build(); for (int i=1;i<=n;i++)//init {
temp.i=i;temp.l=i+_l-1;temp.r=min(i+_r-1,n);if (temp.l>n) continue;
t=query(1,temp.l,temp.r);temp.maxn=t.maxn-a[i-1];temp.pos=t.pos;heap.push(temp);
} for (int i=1;i<=k;i++)//get answer {
temp=heap.top();heap.pop();ans+=temp.maxn; if (temp.l
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |