hdu 2430 线段树维护下标
2012-02-09 19:43
218 查看
求一段连续的区间,使其在满足 和 对p取余不超过k的 前提 下 和最大 。
做法:
用线段树维护区间最小值,最小的下标,即最左边,因为加入sum[i]%p>k就要减去一个sum[id] , sum[id]%p在【sum[i]%p-k,sum[i]%p】之间,
sum[i]-sum[id]的值就为以i结尾的满足条件的连续的一段数的最大值,所以id要尽可能小,所以就是求值在【sum[i]%p-k,sum[i]%p】之间的最左边的数的下标,即满足条件的数的下标最小值。
每次更新时把进过的结点的下标最小值(如果能更新)都更新一遍
View Code
做法:
用线段树维护区间最小值,最小的下标,即最左边,因为加入sum[i]%p>k就要减去一个sum[id] , sum[id]%p在【sum[i]%p-k,sum[i]%p】之间,
sum[i]-sum[id]的值就为以i结尾的满足条件的连续的一段数的最大值,所以id要尽可能小,所以就是求值在【sum[i]%p-k,sum[i]%p】之间的最左边的数的下标,即满足条件的数的下标最小值。
每次更新时把进过的结点的下标最小值(如果能更新)都更新一遍
View Code
#include<cstdio> #include<cstring> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int inf = 1000000000; const int maxn = 1000010; __int64 sum[maxn]; int Min[maxn<<2]; int min(int a,int b){ return a<b?a:b; } void build(int l,int r,int rt){ Min[rt]=inf; if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson); } int update(int num,int id,int l,int r,int rt){ if(l==r&&num==l){ if(id<Min[rt]) Min[rt]=id; return Min[rt]; } int m=(l+r)>>1; int a; if(num<=m) a=update(num,id,lson); if(num>m) a=update(num,id,rson); if(Min[rt]>a) Min[rt]=a; return Min[rt]; } int query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R){ return Min[rt]; } int m=(l+r)>>1; int ret=inf; if(L<=m) ret=min(ret,query(L,R,lson)); if(R>m) ret=min(ret,query(L,R,rson)); return ret; } int main() { int t,ca=1,i,j,k,p,n; scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&p,&k); sum[0]=0; for(i=1;i<=n;i++){ scanf("%d",&j); sum[i]=sum[i-1]+j; } build(0,p-1,1); update(0,0,0,p-1,1); int id=0; int ans=-1; for(i=1;i<=n;i++){ if(sum[i]%p>k) id=query(sum[i]%p-k,sum[i]%p,0,p-1,1); else id=0; if(id!=inf){ if((sum[i]-sum[id])/p>ans) ans=(sum[i]-sum[id])/p; } update(sum[i]%p,i,0,p-1,1); } if(ans==-1) printf("Case %d: %d\n",ca++,-1); else printf("Case %d: %d\n",ca++,ans); } return 0; }
相关文章推荐
- hdu 3397 Sequence Operation 线段树维护区间前后缀和,求子区间连续最值
- HDU 5997 rausen loves cakes (线段树区间维护,启发式区间合并)
- HDU-1540 Tunnel Warfare (线段树 维护端点信息)
- hdu 6070 Dirt Ratio(二分+线段树维护区间最小值)
- HDU 1754 I Hate It(线段树维护 区间最值)
- HDU 6155 Subsequence Count 线段树维护矩阵
- HDU1540 Tunnel Warfare(线段树:维护最大连续子串)
- 2017多校第二场 HDU 6047 Maximum Sequence 线段树或者multiset维护区间最值
- hdu 6070 二分+线段树维护
- HDU-4553-约会安排(线段树维护最长连续区间)
- HDU 5726 GCD (rmq+二分 or 线段树 维护区间gcd)
- hdu 4737 线段树维护+二分
- 【线段树维护区间编号 && 区间更新】HDU - 4614 Vases and Flowers
- HDU 2795 放模板 (线段树_维护最大值,好题)
- HDU 4967(Handling the Past-线段树维护可持久化栈操作)
- hdu 3954 level up 线段树区间维护
- HDU 5454 Excited Database 线段树的维护
- hdu 4288 线段树维护(增删有序数)
- HDU 4521 小明系列问题——小明序列 (线段树维护DP)
- HDU 6070 Dirt Ratio 分数规划 二分 线段树维护区间最值