$Noip2012/Luogu1083$ 借教室
Posted forward777
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$Noip2012/Luogu1083$ 借教室相关的知识,希望对你有一定的参考价值。
$Sol$
区间整体加减? 差分+树状数组维护前缀和!
那每给一个人借完教室之后都要判断一下现在合不合法?那复杂度比暴力还不如些...
注意到这里的单调性,假设给前$x$个人借完教室之后就不合法了,那给前$x+1,x+2.....$个人借教室一定也是不合法的.于是可以二分第一个需要修改申请的人,然后$check()$.$check()$里在借完所有的人教室之后再判断合不合法就好了,而且就用不着树状数组了.
$over.$
$Code$
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> #define il inline #define Rg register #define go(i,a,b) for(Rg int i=a;i<=b;++i) #define yes(i,a,b) for(Rg int i=a;i>=b;--i) #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define db double #define inf 2147483647 using namespace std; il int read() Rg int x=0,y=1;char c=getchar(); while(c<‘0‘||c>‘9‘)if(c==‘-‘)y=-1;c=getchar(); while(c>=‘0‘&&c<=‘9‘)x=(x<<1)+(x<<3)+c-‘0‘;c=getchar(); return x*y; const int N=1000010; int n,m,r[N],d[N],s[N],t[N],a[N],as; il bool ck(int x) mem(a,0); go(i,1,x) a[s[i]]+=d[i]; a[t[i]+1]-=d[i]; Rg int nw=0; go(i,1,n)nw+=a[i];if(nw>r[i])return 1; return 0; int main() n=read(),m=read(); go(i,1,n)r[i]=read(); go(i,1,m)d[i]=read(),s[i]=read(),t[i]=read(); Rg int l=1,r=m,mid; while(l<=r) mid=(l+r)>>1;//cout<<l<<" "<<r<<" "<<mid<<endl; if(ck(mid))as=mid,r=mid-1; else l=mid+1; if(!as)printf("0\n"); else printf("-1\n%d\n",as); return 0;
以上是关于$Noip2012/Luogu1083$ 借教室的主要内容,如果未能解决你的问题,请参考以下文章
洛谷P1083 [NOIP2012提高组Day2T2]借教室