bzoj 3747: [POI2015]Kinoman 线段树
2017-04-19 20:46
423 查看
题意
共有m部电影,编号为1~m,第i部电影的好看值为w[i]。在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部。
你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影。如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值。所以你希望最大化观看且仅观看过一次的电影的好看值的总和。
n,m<=1000000,w[i]<=1000000
分析
还挺有意思的一道题目。考虑一个左端点的贡献.那么我们可以对第一次出现的数的权值赋为正,第二次出现的权值赋为负,其余赋为0,然后求一个最大的前缀和即可。
预处理每个数的下一次出现位置,然后用线段树维护最大前缀和即可。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const int N=1000005; int n,m,w ,f ,ls ,nx ; struct tree{LL tag,mx;}t[N*5]; void pushdown(int d,int l,int r) { if (l==r||!t[d].tag) return; LL w=t[d].tag;t[d].tag=0; t[d*2].tag+=w;t[d*2].mx+=w; t[d*2+1].tag+=w;t[d*2+1].mx+=w; } void ins(int d,int l,int r,int x,int y,int z) { if (x>y) return; pushdown(d,l,r); if (l==x&&r==y) { t[d].tag+=z;t[d].mx+=z; return; } int mid=(l+r)/2; ins(d*2,l,mid,x,min(y,mid),z); ins(d*2+1,mid+1,r,max(x,mid+1),y,z); t[d].mx=max(t[d*2].mx,t[d*2+1].mx); } LL query(int d,int l,int r,int x,int y) { if (x>y) return 0; pushdown(d,l,r); if (l==x&&r==y) return t[d].mx; int mid=(l+r)/2; return max(query(d*2,l,mid,x,min(y,mid)),query(d*2+1,mid+1,r,max(x,mid+1),y)); } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&f[i]); for (int i=1;i<=m;i++) scanf("%d",&w[i]); for (int i=n;i>=1;i--) if (!ls[f[i]]) nx[i]=n+1,ls[f[i]]=i; else nx[i]=ls[f[i]],ls[f[i]]=i; LL ans=0; for (int i=n;i>=1;i--) { if (nx[i]==n+1) ins(1,1,n,i,n,w[f[i]]); else ins(1,1,n,nx[i],nx[nx[i]]-1,-w[f[i]]),ins(1,1,n,i,nx[i]-1,w[f[i]]); ans=max(ans,query(1,1,n,i,n)); } printf("%lld",ans); return 0; }
相关文章推荐
- BZOJ_3747_[POI2015]Kinoman_线段树
- 【BZOJ3747】[POI2015]Kinoman【线段树】
- [BZOJ]3747: [POI2015]Kinoman 线段树
- bzoj 3747 [POI2015]Kinoman 线段树
- Bzoj 3747: [POI2015]Kinoman 线段树
- [BZOJ3747][POI2015]Kinoman(线段树)
- BZOJ3747 [POI2015]Kinoman 【线段树】
- 【bzoj3747】[POI2015]Kinoman 线段树区间合并
- bzoj 3747: [POI2015]Kinoman(线段树)
- [bzoj3747][POI2015]Kinoman_线段树
- BZOJ 3747: [POI2015]Kinoman( 线段树 )
- BZOJ 3747: [POI2015]Kinoman 【线段树】
- [BZOJ 3747] [POI 2015] Kinoman【线段树】
- [bzoj3747][POI2015]Kinoman 线段树
- 【bzoj3747】【POI2015】【Kinoman】【线段树】
- 【BZOJ3747】[POI2015]Kinoman 线段树
- 【bzoj 3747】[POI2015]Kinoman(线段树)
- 【线段树】bzoj3747 [POI2015]Kinoman
- 【BZOJ 3747】 3747: [POI2015]Kinoman (线段树)
- BZOJ 3747 POI2015 Kinoman 线段树