[BZOJ3747][POI2015]Kinoman(线段树)
2017-01-27 17:35
375 查看
题目描述
传送门题解
刚开始想简单了,比较有趣的一道题首先预处理每一个部电影与其相同的下一部电影的位置
首先将所有的电影的第一个赋成正权,第一个的下一个赋成负权,做一遍前缀和每一个点就表示了[1,i]区间的值
左端点向右移动的时候用线段树动态修改和维护
代码
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define LL long long #define N 1000005 const LL inf=1e18; int n,m; int f ,head ,nxt ; LL ans=-inf; LL w ,a ,maxn[N*4],delta[N*4]; void update(int now) { maxn[now]=max(maxn[now<<1],maxn[now<<1|1]); } void pushdown(int now,int l,int r,int mid) { if (delta[now]) { maxn[now<<1]+=delta[now];delta[now<<1]+=delta[now]; maxn[now<<1|1]+=delta[now];delta[now<<1|1]+=delta[now]; delta[now]=0; } } void build(int now,int l,int r) { int mid=(l+r)>>1; if (l==r) { maxn[now]=a[l]; return; } build(now<<1,l,mid); build(now<<1|1,mid+1,r); update(now); } void change(int now,int l,int r,int lr,int rr,LL v) { int mid=(l+r)>>1; if (lr<=l&&r<=rr) { maxn[now]+=v; delta[now]+=v; return; } pushdown(now,l,r,mid); if (lr<=mid) change(now<<1,l,mid,lr,rr,v); if (mid+1<=rr) change(now<<1|1,mid+1,r,lr,rr,v); update(now); } LL query(int now,int l,int r,int lr,LL rr) { int mid=(l+r)>>1; LL ans=-inf; if (lr<=l&&r<=rr) return maxn[now]; pushdown(now,l,r,mid); if (lr<=mid) ans=max(ans,query(now<<1,l,mid,lr,rr)); if (mid+1<=rr) ans=max(ans,query(now<<1|1,mid+1,r,lr,rr)); return ans; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) scanf("%d",&f[i]),nxt[i]=n+1; for (int i=1;i<=m;++i) scanf("%lld",&w[i]),head[i]=n+1; nxt[n+1]=n+1; for (int i=n;i>=1;--i) { nxt[i]=head[f[i]]; head[f[i]]=i; } for (int i=1;i<=m;++i) { if (head[i]<=n) a[head[i]]+=w[i]; if (nxt[head[i]]<=n) a[nxt[head[i]]]-=w[i]; } for (int i=1;i<=n;++i) a[i]+=a[i-1]; build(1,1,n); for (int i=1;i<=n;++i) { int now=i; ans=max(ans,query(1,1,n,now,n)); change(1,1,n,now,n,-w[f[i]]); if (nxt[now]<=n) change(1,1,n,nxt[now],n,2*w[f[i]]),now=nxt[now]; if (nxt[now]<=n) change(1,1,n,nxt[now],n,-w[f[i]]); } printf("%lld\n",ans); }
总结
①相同的只能取一个的要考虑维护当前和它的下一个相关文章推荐
- 【bzoj 3747】[POI2015]Kinoman(线段树)
- bzoj 3747: [POI2015]Kinoman 线段树
- BZOJ_3747_[POI2015]Kinoman_线段树
- 【BZOJ3747】[POI2015]Kinoman【线段树】
- [BZOJ]3747: [POI2015]Kinoman 线段树
- 【线段树】bzoj3747 [POI2015]Kinoman
- bzoj 3747 [POI2015]Kinoman 线段树
- BZOJ 3747 POI2015 Kinoman 线段树
- Bzoj 3747: [POI2015]Kinoman 线段树
- BZOJ 3747 POI 2015 Kinoman 线段树
- BZOJ3747 [POI2015]Kinoman 【线段树】
- 【bzoj3747】[POI2015]Kinoman 线段树区间合并
- bzoj 3747: [POI2015]Kinoman(线段树)
- [bzoj3747][POI2015]Kinoman_线段树
- [bzoj3747][POI2015]Kinoman 线段树
- BZOJ 3747: [POI2015]Kinoman 【线段树】
- BZOJ 3747: [POI2015]Kinoman( 线段树 )
- 【BZOJ3747】[POI2015]Kinoman 线段树
- [BZOJ 3747] [POI 2015] Kinoman【线段树】
- 【BZOJ 3747】 3747: [POI2015]Kinoman (线段树)