【bzoj 1293】[SCOI2009] 生日礼物 指针维护队列
2016-10-18 20:11
399 查看
把所有的点从小到大排序以后,维护 l 和 r 指针,先让 r++ 直到满足题目要求,然后再移动 l 指针 直到不能满足条件为止,但是每一次保证 l 的端点处没有相同的颜色(贪心,要使答案最下),然后每一次更新答案就好了。这样,我们每一次都保证了能够找到一个满足题目条件的区间(而且没有遗漏,因为区间满足单调性),用这个区间去更新答案(正确性),而 l 和 r 都只是向右端点移动,所以时间为
2n (On)。最后,由于上一次在写cf比赛的时候我自信的直接在原数组上处理,结果左右指针越界,wa了几发,心有余悸就收写了一个队列来维护。
不过其实大同小异,各位大牛应该用不着这么麻烦。
2n (On)。最后,由于上一次在写cf比赛的时候我自信的直接在原数组上处理,结果左右指针越界,wa了几发,心有余悸就收写了一个队列来维护。
不过其实大同小异,各位大牛应该用不着这么麻烦。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define maxn 1000020 using namespace std; int n,k,cnt,ans; int vis[63]; int read(){ char c=getchar();int x=0; for(;c>'9'||c<'0';c=getchar()); for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0'; return x; } struct node{ int x,id; bool operator<(const node& b)const{return id<b.id;} }nod[maxn]; int q[maxn*2],l=1,r; void solve(){ ans=1e9; int tot=0; for(int i=1;i<=cnt;i++){ if(vis[nod[i].x]==0)tot++; vis[nod[i].x]++; q[++r]=i; while(nod[q[l]].x==nod[q[l+1]].x)vis[nod[q[l]].x]--,l++; while(tot>=k){ ans=min(ans,nod[i].id-nod[q[l]].id); vis[nod[q[l]].x]--; if(vis[nod[q[l]].x]==0)tot--; l++; } } printf("%d",ans); } int main(){ scanf("%d%d",&n,&k); for(int x,y,i=1;i<=k;i++){ x=read(); for(int j=1;j<=x;j++){ y=read(); nod[++cnt].x=i,nod[cnt].id=y; } } sort(nod+1,nod+1+cnt); solve(); return 0; }
相关文章推荐
- [BZOJ 1293] SCOI 2009 生日礼物 · 单调队列
- [BZOJ1293][SCOI2009]生日礼物(单调队列)
- [BZOJ 1293][SCOI2009]生日礼物:单调队列
- 【bzoj 1293】[SCOI2009]生日礼物(乱搞|单调队列)
- bzoj 1293: [SCOI2009]生日礼物 (单调队列)
- bzoj 1293: [SCOI2009]生日礼物【单调队列】
- BZOJ 1293: [SCOI2009]生日礼物【单调队列】
- [bzoj1293][SCOI2009]生日礼物(单调队列)
- [bzoj1293][SCOI2009]生日礼物 单调队列优化dp
- BZOJ 1293: [SCOI2009]生日礼物【毛毛虫】
- [bzoj 1293][SCOI2009] 生日礼物
- [bzoj 1293] [SCOI2009]生日礼物
- 【bzoj1293】【SCOI2009】【生日礼物】
- BZOJ系列1293《[SCOI2009]生日礼物》题解
- bzoj 1293: [SCOI2009]生日礼物
- BZOJ 1293 SCOI2009 生日礼物 堆
- BZOJ1293: [SCOI2009]生日礼物
- [BZOJ1293][SCOI2009]生日礼物-堆
- 【BZOJ1293】【SCOI2009】生日礼物
- BZOJ 1293 [SCOI2009] 生日礼物