zoukankan      html  css  js  c++  java
  • FJUT 借教室 (线段树区间查询+区间修改)


     

    解题思路:看到题目,经典的区间查询+区间修改,我们用线段树维护一段区间的最小值,每当有新的订单,我们就先查询订单时间范围内的最小教室数量,然后与Dj作比较,如果比dj小,那么我们可以标记为false,然后后面的操作都不用看了,因为他只要求输出第一个不满足的订单,否则就按照订单进行区间修改,即在该订单的开始时间和结束时间这个范围内都减少dj个教室。

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int INF = 0x3f3f3f3f3f3f3f3f;
    const int N = 1000005;
    ll a[N],tree[N<<2],lazy[N<<2];
    int n,m;
    
    void pushup(int k) {
    	tree[k] = min(tree[k<<1],tree[k<<1|1]);//将父节点更新为较小的值
    }
    
    void pushdown(int k) {
    	if(lazy[k]) {
    		lazy[k<<1] += lazy[k];
    		lazy[k<<1|1] += lazy[k];
    		
    		tree[k<<1] += lazy[k];
    		tree[k<<1|1] += lazy[k];
    		lazy[k] = 0;
    	}
    }
    
    void build(int l,int r,int k) {
    	if(l == r) {
    		tree[k] = a[l];
    	}
    	else {
    		int mid = l + ((r - l) >> 1);
    		build(l,mid,k<<1);
    		build(mid+1,r,k<<1|1);
    		pushup(k);
    	}
    }
    
    void updata(int L, int R, int v, int l, int r,int k) {
    	if(L <= l && r <= R) {
    		tree[k] += v;
    		lazy[k] += v;
    	}
    	else {
    		pushdown(k);
    		int mid = l + ((r - l) >> 1);
    		if(L <= mid) {
    			updata(L,R,v,l,mid,k<<1);
    		}
    		if(R > mid) {
    			updata(L,R,v,mid+1,r,k<<1|1);
    		}
    		pushup(k);
    	}
    }
    
    ll query(int L,int R,int l,int r,int k) {
    	if(L <= l && r <= R) {
    		return tree[k];
    	}
    	else {
    		pushdown(k);
    		ll res = INF;
    		int mid = l + ((r - l) >> 1);
    		if(L <= mid) {
    			res = min(res,query(L,R,l,mid,k<<1));
    		}
    		if(R > mid) {
    			res = min(res,query(L,R,mid+1,r,k<<1|1));
    		}
    		return res;
    	}
    }
    
    int main()
    {
    	int u,v;
    	ll w;
    //	freopen("X:Âå¹È²âÊÔÊý¾ÝP1083_2.in","r",stdin);
    	scanf("%d%d",&n,&m);
    	memset(lazy,0,sizeof lazy);
    	for(int i = 1;i <= n; ++i) {
    		scanf("%lld",&a[i]);
    	}
    	build(1,n,1);
    	int fg = 0;//这个标记是否已经不满足条件
    	for(int i = 1;i <= m; ++i) {
    		scanf("%lld%d%d",&w,&u,&v);
    		if(fg)
    			continue;
    		int k = query(u,v,1,n,1);
    		if(k < w) {
    			fg = i;
    		}
    		else {
    			updata(u,v,-w,1,n,1);
    		}
    	}
    	if(!fg) {
    		puts("0");
    	}
    	else {
    		printf("-1
    %d
    ",fg);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Struts2中There is no Action mapped for namespace错误解决方法
    String字符串常量池简介
    main方法中参数"String[ ] args"详解
    自定义异常基本用法
    finally关键字执行的底层原理
    Linux环境下安装mysql5.6(二进制包不是rpm格式)
    finalize关键字小结
    "=="和equals小结
    super关键字小结(构造方法的执行是不是一定会创建对象?)
    冒泡排序
  • 原文地址:https://www.cnblogs.com/Mangata/p/14290559.html
Copyright © 2011-2022 走看看