51Nod 1672 扫描线 + 线段树/树状数组
来源:互联网 发布:淘宝卖家真实现状 编辑:程序博客网 时间:2024/06/10 21:23
题目大意,给定n个数字和m个区间,和k
题解:首先不难发现这个题没法直接做,STL上了个错的思想,即每个区间都+1然后对于被覆盖了k+次的区间做最大字段和,显然是错的。
考虑枚举答案的右端点,显然左端点越远越不可能是答案,而左端点越远效果越好。并且注意到一个区间是覆盖[l,r]当且仅当这个区间既覆盖l,又覆盖r。这样每次r+1,就把不覆盖r的区间删去,把覆盖了r的区间加上。然后考虑左端点,如果左端点被少于k个区间覆盖,那么l++。
最后用所有的合法的[l,r]更新答案即可,上述可用线段树或者树状数组实现,由于每个区间只会被计算一次,所以复杂度O(nlgn).
考试的时候多组数据。
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<vector>#define N 100010#define lint long longusing namespace std;struct segment{ int s,l,r,pt; segment *ch[2];}*rt;inline int update_tags(segment* &rt,int v){ return rt->pt+=v,rt->s+=v;}inline int push_down(segment* &rt){ update_tags(rt->ch[0],rt->pt); update_tags(rt->ch[1],rt->pt); return rt->pt=0;}int build(segment* &rt,int l,int r){ rt=new segment;rt->l=l,rt->r=r; rt->s=rt->pt=0;if(l==r) return 0; int mid=(l+r)>>1; build(rt->ch[0],l,mid); build(rt->ch[1],mid+1,r); return 0;}int Clear(segment* &rt){ rt->s=rt->pt=0;if(rt->l==rt->r) return 0; Clear(rt->ch[0]),Clear(rt->ch[1]);return 0;}int update(segment* &rt,int s,int t,int v){ int l=rt->l,r=rt->r,mid=(l+r)>>1; if(s<=l&&r<=t) return update_tags(rt,v); if(rt->pt) push_down(rt); if(s<=mid) update(rt->ch[0],s,t,v); if(mid<t) update(rt->ch[1],s,t,v); return 0;}int query(segment* &rt,int p){ int l=rt->l,r=rt->r,mid=(l+r)>>1; if(l==r) return rt->s; if(rt->pt) push_down(rt); if(p<=mid) return query(rt->ch[0],p); else return query(rt->ch[1],p);}int a[N];lint s[N],ans;vector<int> L[N],R[N];int main(){ int n,k,m;build(rt,1,N); while(scanf("%d%d%d",&n,&k,&m)!=EOF) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i]; for(int i=1;i<=n;i++) L[i].clear(),R[i].clear(); Clear(rt);ans=0LL; for(int i=1;i<=m;i++) { int s,t;scanf("%d%d",&s,&t); L[s].push_back(t),R[t].push_back(s); } for(int r=1,l=1;r<=n;r++) { for(int i=0;i<R[r-1].size();i++) update(rt,R[r-1][i],r-1,-1); for(int i=0;i<L[r].size();i++) update(rt,r,L[r][i],1); while(l<=r&&query(rt,l)<k) l++; if(l<=r) ans=max(ans,s[r]-s[l-1]); } printf("%lld\n",ans); } return 0;}
阅读全文