bzoj 2482: [Spoj1557] Can you answer these queries II
2015-06-16 20:27
543 查看
Description
给定n个元素的序列。给出m个询问:求l[i]~r[i]的最大子段和(可选空子段)。
这个最大子段和有点特殊:一个数字在一段中出现了两次只算一次。
比如:1,2,3,2,2,2出现了3次,但只算一次,于是这个序列的和是1+2+3=6。
Input
第一行一个数n。第二行n个数,为给定的序列,这些数的绝对值小于等于100000。
第三行一个数m。
接下来m行,每行两个数,l[i],r[i]。
Output
M行,每行一个数,为每个询问的答案。Sample Input
94 -2 -2 3 -1 -4 2 2 -6
3
1 2
1 5
4 9
Sample Output
45
3
HINT
【数据说明】30%:1 <= n, m <= 100
100%:1 <= n, m <= 100000
Source
spoj gss2枚举右端点。我们用线段树维护以这个点开始到当前点的ans和过去最大ans
然后离线回答询问即可
#include<cstdio> #include<string> #include<cstring> #include<algorithm> using namespace std; struct tree { int l,r; long long m,vm; long long tag,vtag; }tr[800001]; struct que { int l,r; int p; long long ans; }ask[100001]; inline bool cmp1(que x,que y) { if(x.r<y.r) return true; return false; } inline bool cmp2(que x,que y) { if(x.p<y.p) return true; return false; } inline void up(int p) { tr[p].m=max(tr[p*2].m,tr[p*2+1].m); tr[p].vm=max(tr[p*2].vm,tr[p*2+1].vm); } inline void push(int p) { tr[p*2].vm=max(tr[p*2].vm,tr[p*2].m+tr[p].vtag); tr[p*2+1].vm=max(tr[p*2+1].vm,tr[p*2+1].m+tr[p].vtag); tr[p*2].m+=tr[p].tag; tr[p*2+1].m+=tr[p].tag; tr[p*2].vtag=max(tr[p*2].vtag,tr[p*2].tag+tr[p].vtag); tr[p*2+1].vtag=max(tr[p*2+1].vtag,tr[p*2+1].tag+tr[p].vtag); tr[p*2].tag+=tr[p].tag; tr[p*2+1].tag+=tr[p].tag; tr[p].tag=0; tr[p].vtag=0; } inline void build(int p,int l,int r) { tr[p].l=l; tr[p].r=r; if(l!=r) { int mid=(l+r)/2; build(p*2,l,mid); build(p*2+1,mid+1,r); up(p); } } inline void add(int p,int l,int r,long long x) { if(l>r) return ; /* if(l==0) l=1;*/ if(l<=tr[p].l&&tr[p].r<=r) { tr[p].m+=x; tr[p].tag+=x; tr[p].vm=max(tr[p].vm,tr[p].m); tr[p].vtag=max(tr[p].vtag,tr[p].tag); } else { push(p); int mid=(tr[p].l+tr[p].r)/2; if(l<=mid) add(p*2,l,r,x); if(r>mid) add(p*2+1,l,r,x); up(p); } } inline long long askx(int p,int l,int r) { if(l<=tr[p].l&&tr[p].r<=r) return tr[p].vm; else { push(p); int mid=(tr[p].l+tr[p].r)/2; long long ans=0; if(l<=mid) ans=max(ans,askx(p*2,l,r)); if(r>mid) ans=max(ans,askx(p*2+1,l,r)); return ans; } } int a[1000001]; int pre[1000001],la[1000001]; int main() { // freopen("sequence.in","r",stdin); // freopen("sequence.out","w",stdout); int n; scanf("%d",&n); int i; for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=n;i++) { pre[i]=la[a[i]]; la[a[i]]=i; } build(1,1,n); int m; scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%d%d",&ask[i].l,&ask[i].r); ask[i].p=i; } sort(ask+1,ask+1+m,cmp1); int d=1; for(i=1;i<=n;i++) { add(1,pre[i]+1,i,a[i]); while(d<=m&&ask[d].r==i) { ask[d].ans=askx(1,ask[d].l,ask[d].r); d++; } } sort(ask+1,ask+1+m,cmp2); for(i=1;i<=m;i++) printf("%lld\n",ask[i].ans); return 0; }
相关文章推荐
- servlet跳转(RequestDispatcher)的获取
- iOS中UIView之间布局及跳转的几种方式
- HBuilder:一个不错的web前端IDE(代码编辑器)
- Confluence Wiki Markup & Markdown
- Cannot convert value '0000-00-00 00:00:00' from column 1 to TIMESTAMP分析及解决办法
- Cannot convert value '0000-00-00 00:00:00' from column 1 to TIMESTAMP解决办法
- Soapui Pro 使用
- NGUI 合集
- SQuirreL SQL Client数据库图形化管理客户端
- Java 信任所有SSL证书(解决PKIX path building failed问题)
- Selenium2学习-010-WebUI自动化实战实例-008-Selenium 操作下拉列表实例-Select
- ios的手势操作之UIGestureRecognizer
- ios UIDatePicker语言设置
- 156 UIImageView 和 CADisplayLink 实现 Tom 汤姆猫动画效果的区别(扩展知识:分组(黄色文件夹)和文件夹引用(蓝色文件夹)区别)
- UIView
- 统计easyui datagrid某列之和显示在对应列下面
- Android中蓝牙的基本应用--BluetoothAdapter类
- java 兑现固定长度的java.util.Queue
- Android bluetooth 蓝牙开发/蓝牙协议/蓝牙通信
- Index & Statistics ->> Rebuild Index会不会覆盖原先Index的WITH选项设置