poj 3017

#include<iostream> using namespace std; #define MAXN 100003 #define INF ((1LL)<<60) long long dp[MAXN]; int f[MAXN]; int b[MAXN]; long long sum[MAXN]; struct SegTree{ int left[MAXN*4],right[MAXN*4]; long long _min[MAXN*4]; inline void build(int l,int r,int k){ left[k]=l; right[k]=r; if(l==r){ _min[k]=INF; return ; } int m=(l+r)>>1; build(l,m,k*2); build(m+1,r,k*2+1); push_up(k); } inline void push_up(int k){ _min[k]=(_min[k*2]<_min[k*2+1]?_min[k*2]:_min[k*2+1]); return ; } inline long long getMin(){ return _min[1]; } inline void insert(int ind,long long val,int k){ if(left[k]==right[k]){ _min[k]=val; return ; } int mid=(left[k]+right[k])>>1; if(ind<=mid) insert(ind,val,k*2); else insert(ind,val,k*2+1); push_up(k); return ; } inline void delet(int ind,int k){ if(left[k]==right[k]){ _min[k]=INF; return ; } int mid=(left[k]+right[k])>>1; if(ind<=mid) delet(ind,k*2); else delet(ind,k*2+1); push_up(k); } }sgt; struct node{ int val,pos; }queue[MAXN]; int front,back; void del(int j){ while(front!=back){ if(queue[front].pos<=j) { if(front+1<back) sgt.delet(queue[front].pos,1); front++; } else break; } } void ins(int i){ int val=f[i]; while(front!=back){ if(queue[back-1].val<=val){ if(front+1<back) sgt.delet(queue[back-2].pos,1); back--; } else break; } queue[back].val=val; queue[back++].pos=i; if(back-front>1) sgt.insert(queue[back-2].pos,dp[queue[back-2].pos]+queue[back-1].val,1); } int binarySearch(long long m,int i){ int low=1,high=i,mid; while(low<=high){ int mid=(low+high)>>1; if(sum[i]-sum[mid-1]<=m) high=mid-1; else low=mid+1; } return high; } void initB(int n,long long m){ int i; for(i=1;i<=n;i++) b[i]=binarySearch(m,i); } void process(int n,long long m){ sgt.build(0,n,1); dp[0]=0; int i,j; front=back=0; int pre; for(i=1;i<=n;i++){ del(b[i]); ins(i); pre=b[i]; dp[i]=dp[pre]+queue[front].val; long long tmp=sgt.getMin(); if(tmp!=INF){ if(tmp<dp[i]) dp[i]=tmp; } } } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int n; long long m; while(scanf("%d%I64d",&n,&m)!=EOF){ // cout<<m<<endl; int i; for(i=1;i<=n;i++) scanf("%d",&f[i]); for(i=1;i<=n;i++) if(f[i]>m) break; if(i<=n){printf("-1/n");continue;} sum[0]=0; for(i=1;i<=n;i++) sum[i]=sum[i-1]+f[i]; initB(n,m); process(n,m); printf("%lld/n",dp[n]); } }  

 

你可能感兴趣的:(struct,insert,Build,UP)