• 【*2000】【2018-2019 ICPC, NEERC, Southern Subregional Contest C 】Cloud Computing


    【链接】 我是链接,点我呀:)
    【题意】

    【题解】

    我们可以很容易知道区间的每个位置有哪些安排可以用。 显然 我们优先用那些花费的钱比较少的租用cpu方案。 但一个方案可供租用的cpu有限。 我们可以用一个线段树 线段树的下标表示价格。 那一位的值,为这个价格的cpu能租多少个。 弄个区间和(即这个价格的区间总共能租多少个(最多) 再弄另外一个区间和sum表示价格区间内的所有cpu都租,要花多少钱。 因为每个位置最多要租k个cpu 利用上面的两个区间和则我们可以在线段树上做一个二分。 找到租前k个最便宜的cpu要多少钱。(类似平衡树的前k小的和) (优先价格低的,所以先把左子树选完,如果还不够,再到右子树里面选(左子树直接累加它的价格和就好) ) (如果最后发现l==r,说明当前这个价格l至少有k个,因为你不能多选,所以你恰好选k个就ok 注意线段树的右端点是1e6,而不是n.

    【代码】

    #include <bits/stdc++.h>
    #define ll long long
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    using namespace std;
    
    const int N = 1e6;
    
    ll sc[N*4+10],sum[N*4+10];
    
    vector<pair<int,int> > in[N+10],out[N+10];
    int n,k,m,curi;
    
    void _updata(int l,int r,int rt,int price,int num){
     	if (l==r){
     	    sc[rt]+=num;
     	    sum[rt]+=1LL*price*num;
     	    return;
     	}
    	int mid = (l+r)>>1;
    	if (price<=mid)
    		_updata(lson,price,num);
    	else
    		_updata(rson,price,num);
    	sc[rt]=sc[rt<<1]+sc[rt<<1|1];
    	sum[rt] = sum[rt<<1]+sum[rt<<1|1];	 	
    }
    
    ll _query(int l,int r,int rt,int k){
    	if (k==0) return 0;
     	if (sc[rt]<=k) return sum[rt];
     	if (l==r){
     	 	return 1LL*k*l;
     	}
     	//sc[rt]>k
     	int mid = (l+r)>>1;
     	ll temp = 0;
    	if (sc[rt<<1]<=k) temp+=sum[rt<<1];else return _query(lson,k);
    	return temp + _query(rson,k-sc[rt<<1]);	
    }
    
    int main(){
    	#ifdef ccy
    			freopen("rush.txt","r",stdin);
    	#endif
    	scanf("%d%d%d",&n,&k,&m);
    	rep1(i,1,m){
    	 	int x,y,num,p;
    	 	scanf("%d%d%d%d",&x,&y,&num,&p);
    	 	in[x].push_back(make_pair(num,p));
    	 	out[y+1].push_back(make_pair(num,p));
    	}
    	ll ans = 0;
    	rep1(i,1,n){
    		curi = i;
    	 	rep1(j,0,(int) in[i].size()-1){
    	 	 	int num = in[i][j].first,price = in[i][j].second;
    	 	 	_updata(1,N,1,price,num);
    	 	}
    	 	rep1(j,0,(int) out[i].size()-1){
    	 	 	int num = out[i][j].first,price = out[i][j].second;
    	 	 	_updata(1,N,1,price,-num);
    	 	}
    	 	ll temp1 = _query(1,N,1,k);
    		ans += temp1;
    	}
    	printf("%lld
    ",ans);
     	return 0;
    }
    
  • 相关阅读:
    ntp
    mknod
    timeout/timelimit
    Eclipse 包变成文件夹
    Eclipse 包变成文件夹
    Java生成随机字符串和随即生成10以内的字符串
    Java生成随机字符串和随即生成10以内的字符串
    插入排序
    插入排序
    Java 中基本类型和包装类之间的转换
  • 原文地址:https://www.cnblogs.com/AWCXV/p/9932869.html
Copyright © 2020-2023  润新知