洛谷 P1083 借教室【二分+差分/线段树】
2018-09-13 21:54
232 查看
二分mid,然后用1~mid的操作在差分序列上加减,最后把差分序列前缀和起来,看是否有有超过初始r值的
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e6,INF=1e9; long long n,m,a ,d ,x ,y ,s ; int read() { int r=0,f=1; char p=getchar(); while(p>'9'||p<'0') { if(p=='-') f=-1; p=getchar(); } while(p>='0'&&p<='9') { r=r*10+p-48; p=getchar(); } return r*f; } bool ok(int m) { memset(s,0,sizeof(s)); for(int i=1;i<=m;i++) s[x[i]]+=d[i],s[y[i]+1]-=d[i]; long long sum=0; for(int i=1;i<=n;i++) { sum+=s[i]; if(sum>a[i]) return 0; } return 1; } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=m;i++) d[i]=read(),x[i]=read(),y[i]=read(); int l=0,r=m,ans=0; while(l<=r) { int mid=(l+r)>>1; if(ok(mid)) l=mid+1,ans=mid; else r=mid-1; } if(ans==m) printf("0"); else printf("-1\n%d",ans+1); return 0; }
线段树,模拟即可,洛谷上会T一个点(开O2能过)
#include<iostream> #include<cstdio> using namespace std; const int N=1000005; int n,m,a ; struct xds { int l,r,mn,lz; }t[N<<1]; int read() { int r=0,f=1; char p=getchar(); while(p>'9'||p<'0') { if(p=='-') f=-1; p=getchar(); } while(p>='0'&&p<='9') { r=r*10+p-48; p=getchar(); } return r*f; } void pd(int ro) { if(t[ro].lz!=0) { t[ro<<1].mn+=t[ro].lz,t[ro<<1].lz+=t[ro].lz; t[ro<<1|1].mn+=t[ro].lz,t[ro<<1|1].lz+=t[ro].lz; t[ro].lz=0; } } void build(int ro,int l,int r) { t[ro].l=l,t[ro].r=r; if(l==r) { t[ro].mn=a[l]; return; } int mid=(l+r)>>1; build(ro<<1,l,mid); build(ro<<1|1,mid+1,r); t[ro].mn=min(t[ro<<1].mn,t[ro<<1|1].mn); } void update(int ro,int l,int r,int v) { if(t[ro].l==l&&t[ro].r==r) { t[ro].mn+=v,t[ro].lz+=v; return; } pd(ro); int mid=(t[ro].l+t[ro].r)>>1; if(r<=mid) update(ro<<1,l,r,v); else if(l>mid) update(ro<<1|1,l,r,v); else update(ro<<1,l,mid,v),update(ro<<1|1,mid+1,r,v); t[ro].mn=min(t[ro<<1].mn,t[ro<<1|1].mn); } int ques(int ro,int l,int r) { if(t[ro].l==l&&t[ro].r==r) return t[ro].mn; pd(ro); int mid=(t[ro].l+t[ro].r)>>1; if(r<=mid) return ques(ro<<1,l,r); else if(l>mid) return ques(ro<<1|1,l,r); else return min(ques(ro<<1,l,mid),ques(ro<<1|1,mid+1,r)); } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); build(1,1,n); for(int i=1;i<=m;i++) { int d=read(),x=read(),y=read(),mn=ques(1,x,y); if(d>mn) { printf("-1\n%d\n",i); return 0; } update(1,x,y,-d); } puts("0"); return 0; }
相关文章推荐
- VIjos——V 1782 借教室 | | 洛谷——P1083 借教室
- 洛谷 1083||NOIP 2012 借教室 二分答案+差分 解题报告
- ●洛谷P1083 借教室
- NOIP 2012 T5 借教室 [洛谷P1083]
- Codevs 1217 && 洛谷 P1083 借教室
- [NOIP2012] 提高组 洛谷P1083 借教室
- 借教室 洛谷1083 差分+二分
- 洛谷 P1083 [NOIP2012 D2T2] 借教室
- 洛谷 P1083 借教室
- 洛谷 P1083 借教室
- 洛谷P1083 [NOIP2012提高组Day2T2]借教室
- 洛谷 P1083 借教室
- 二分查找or线段树(借教室洛谷1083vijos1782NOIP 2012 提高组 第二天 第二题)
- [洛谷]P1083 借教室
- 【分块】【常数优化】【Orz faebdc】洛谷 P1083 NOIP2012提高组 借教室
- 洛谷 1083 [NOIP2012] 借教室 二分
- [POI2010]TES-Intelligence Test 洛谷3500 二分
- LuoguP1083 借教室[NOIP2012] 解题报告【二分答案+差分】
- NOIP2012 借教室【二分答案+前缀和】
- 【NOIP2012】【CJOJ1093】【洛谷1083】借教室