p1245
理解题意就还好吧:刚开始区间内每一个点权值为是s.对于每一个申请,如果能卖就输出yes并卖票,否则输出no.
这不是模拟么?策略都在了.然而c<=30000是会超时的,我们需要一个高级数据结构.
判断能不能卖=询问区间最小值,这个可以用线段树的.而线段树也支持区间修改,这道题就可以开始写了.
输入的 右端点要-1,因为右端点就下车了.
using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} return x*f; } using namespace std; int i,tn,tl,tr; int minn[400010],reduce[400010]; int c,s,r; void build(int now,int l,int r) { minn[now]=s; if(l==r) return; int mid=(l+r)/2; build(now<<1,l,mid); build((now<<1)+1,mid+1,r); } void pushdown(int now) { if(reduce[now]) { reduce[now<<1]+=reduce[now]; reduce[(now<<1)+1]+=reduce[now]; minn[now<<1]-=reduce[now]; minn[(now<<1)+1]-=reduce[now]; reduce[now]=0; } } void change(int now,int l,int r) { if(tl<=l&&r<=tr) { minn[now]-=tn; reduce[now]+=tn; return; } int mid=(l+r)/2; int lc=now<<1; int rc=(now<<1)+1; pushdown(now); if(tl<=mid) change(lc,l,mid); if(tr>mid) change(rc,mid+1,r); minn[now]=min(minn[lc],minn[rc]); } int ask(int now,int l,int r) { if(tl<=l&&r<=tr) return minn[now]; int mid=(l+r)/2; int lc=now<<1; int rc=(now<<1)+1; pushdown(now); int ans=60010; if(tl<=mid) ans=ask(lc,l,mid); if(tr>mid) ans=min(ans,ask(rc,mid+1,r)); return ans; } int main() { cin>>c>>s>>r; build(1,1,c); for(i=1;i<=r;i++) { cin>>tl>>tr>>tn; tr--; if(ask(1,1,c)>=tn) { cout<<"YES"<<endl; change(1,1,c); } else cout<<"NO"<<endl; } return 0; }