【bzoj3747】[POI2015]Kinoman 线段树
2016-01-07 08:21
260 查看
经典做法,处理出next[i]表示下一个相同的地方。
注意是算出现且仅出现一次的地方。
每次加一个颜色就是[i,next[i]-1]这个区间+价值
删除一个颜色就是[i,next[i-1]]这个区间-价值
所以用一个线段树维护每个位置的答案,支持区间加和查询就可以了。
注意是算出现且仅出现一次的地方。
每次加一个颜色就是[i,next[i]-1]这个区间+价值
删除一个颜色就是[i,next[i-1]]这个区间-价值
所以用一个线段树维护每个位置的答案,支持区间加和查询就可以了。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<iostream> #define maxn 1000100 using namespace std; struct yts { long long tag,mx; int l,r; }t[4*maxn]; int a[maxn],last[maxn],next[maxn]; long long b[maxn]; int n,m; long long ans; void build(int i,int l,int r) { t[i].l=l;t[i].r=r; if (l==r) return; int mid=(l+r)/2; build(i*2,l,mid); build(i*2+1,mid+1,r); } void add(int i,long long d) { t[i].mx+=d;t[i].tag+=d; } void release(int i) { if (t[i].l==t[i].r) return; if (t[i].tag) { add(i*2,t[i].tag);add(i*2+1,t[i].tag); t[i].tag=0; } } long long query(int i,int l,int r) { if (l<=t[i].l && t[i].r<=r) return t[i].mx; release(i); int mid=(t[i].l+t[i].r)/2; long long ans=0; if (l<=mid) ans=max(ans,query(i*2,l,r)); if (mid<r) ans=max(ans,query(i*2+1,l,r)); return ans; } void modify(int i,int l,int r,long long d) { if (l<=t[i].l && t[i].r<=r) {add(i,d);return;} release(i); int mid=(t[i].l+t[i].r)/2; if (l<=mid) modify(i*2,l,r,d); if (mid<r) modify(i*2+1,l,r,d); t[i].mx=max(t[i*2].mx,t[i*2+1].mx); } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); next[last[a[i]]]=i; last[a[i]]=i; } for (int i=1;i<=m;i++) next[last[i]]=n+1; for (int i=1;i<=m;i++) scanf("%lld",&b[i]); build(1,1,n); memset(last,0,sizeof(last)); for (int i=1;i<=n;i++) if (!last[a[i]]) { modify(1,i,next[i]-1,b[a[i]]); last[a[i]]=i; } for (int i=1;i<=n;i++) { ans=max(ans,query(1,i,n)); modify(1,i,next[i]-1,-b[a[i]]); if (next[i]!=n+1) modify(1,next[i],next[next[i]]-1,b[a[i]]); } printf("%lld\n",ans); return 0; }
相关文章推荐
- 用<a>提交表单
- 公益筹款项目两则,身边真事,求关注或转发,感谢大家
- FAQ系列 | B+树索引和哈希索引的区别
- Struts2值栈的相关操作
- SSH框架
- PPP立法结束征求意见 财政部门赢得主导地位
- android学习9——Handler简单用法
- Scrapy系列教程(2)------Item(结构化数据存储结构)
- var和dynamic的区别及如何正确使用dynamic ?
- Android:3G网络是否可用
- 2015年开发业界十大技术视频排行榜
- Android:反编译APK
- Android:SIM信息获取
- 很不错的jQuery学习资料和实例
- ES6学习——新的语法:for..of 循环
- 判断素数和输出100以内的素数
- 在jmeter测试mysql中如何一次运行多条sql语句
- 在jmeter测试mysql中如何一次运行多条sql语句
- 在jmeter测试mysql中如何一次运行多条sql语句
- 2016【太原网络营销师】郭文军教你如何学网络营销