牛客竞赛——P1314 聪明的质监员(二分+前缀和)(来源落谷)

 

第一:二分的判断。

可以看到:在W取0时,所有的区间内的矿石都可以选上,

而在W大于最大的质量时,所有的矿石都选不上。

然后简单算一下就发现:

W越大,矿石选的越少,W越小,矿石选的越多

所以,随着W增大,Y值减小;

所以:二分的判断条件出来了:

当Y>s时,需要增大W来减小Y,从而|Y-s|变小;

当Y==s时,|Y-s|==0;

当Y<s时,需要减小W来增大Y,从而|Y-s|变大;

第二:前缀和。

我们在计算一个区间的和时(虽然这里是两个区间和再相乘,但没关系)

通常是用前缀和的方法来缩减时间,直接模拟是n*n的,而前缀和成了2*n

很显然:

在w[i]>=Ww[i]>=W时这个i矿石会在统计里(若<W就不管它了直接pre[i]=pre[i-1]),

矿石价值和是:pre_v[i]=pre_v[i-1]+v[i],前面的和加上当前这一个i矿石;

矿石数量和是:pre_n[i]=pre_n[i-1]+1,数量加1嘛。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
ll w[200010],v[200010],pre_w[200010],pre_v[200010];
ll l[200010],r[200010];
ll n;
//处理前缀和 
void pre(ll W){
	for(int i=1;i<=n;i++){
		if(w[i]>=W){
			pre_w[i]=pre_w[i-1]+1;
			pre_v[i]=pre_v[i-1]+v[i];
		}
		else {
			pre_w[i]=pre_w[i-1];
			pre_v[i]=pre_v[i-1];
		}
	}
}
int main(){
	ll m,s,W=0;
	scanf("%lld %lld %lld",&n,&m,&s);
	for(int i=1;i<=n;i++){
		scanf("%lld %lld",&w[i],&v[i]);
		W=max(W,w[i]);
	}
	for(int i=1;i<=m;i++){
		scanf("%lld %lld",l+i,r+i);
	}
	ll low=0,high=W+1;
	ll minn=0x3f3f3f3f3f3f3f3f;//这里必须是8个3f,,long long 的无穷大 
	while(low<=high){
		W=(low+high+1)>>1;
		ll y=0;
		//前缀和 
		pre(W); 
		//累加yi; 
		for(int i=1;i<=m;i++){
			y+=((pre_w[r[i]]-pre_w[l[i]-1])*(pre_v[r[i]]-pre_v[l[i]-1]));
		}
		//y==s直接得出最小值 
		if(y==s){
			minn=0;
			break;
		}
		if(y<s){
			high=W-1;///w和y变化是成负相关的 
		}
		else low=W+1;
		minn=min(minn,abs(y-s));
		memset(pre_w,0,sizeof(pre_w));
		memset(pre_v,0,sizeof(pre_v));
	}
	printf("%lld\n",minn);
	//cout<<minn<<endl;
	return 0;
}
//            /\       |  /  |**、
//			 /  \      | /   |   \
//			/    \     |/    |   /  _____                      ____   |  /
//		   /------\    |\    |__/  /     \  \      /\      /  /    \  | /
//		  /        \   | \   |    /       \  \    /  \    /  /______\ |/
//		 /          \  |  \  |    \       /   \  /    \  /   \        |
//      /            \ |   \ |     \_____/     \/      \/     \_____  |
/**
 *        ┏┓    ┏┓
 *        ┏┛┗━━━━━━━┛┗━━━┓
 *        ┃       ┃  
 *        ┃   ━    ┃
 *        ┃ >   < ┃
 *        ┃       ┃
 *        ┃... ⌒ ...  ┃
 *        ┃       ┃
 *        ┗━┓   ┏━┛
 *          ┃   ┃ Code is far away from bug with the animal protecting          
 *          ┃   ┃   神兽保佑,代码无bug
 *          ┃   ┃           
 *          ┃   ┃        
 *          ┃   ┃
 *          ┃   ┃           
 *          ┃   ┗━━━┓
 *          ┃       ┣┓
 *          ┃       ┏┛
 *          ┗┓┓┏━┳┓┏┛
 *           ┃┫┫ ┃┫┫
 *           ┗┻┛ ┗┻┛
 */
// warm heart, wagging tail,and a smile just for you!
//
//                            _ooOoo_
//                           o8888888o
//                           88" . "88
//                           (| -_- |)
//                           O\  =  /O
//                        ____/`---'\____
//                      .'  \|     |//  `.
//                     /  \|||  :  |||//  \
//                    /  _||||| -:- |||||-  \
//                    |   | \\  -  /// |   |
//                    | \_|  ''\---/''  |   |
//                    \  .-\__  `-`  ___/-. /
//                  ___`. .'  /--.--\  `. . __
//               ."" '<  `.___\_<|>_/___.'  >'"".
//              | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//              \  \ `-.   \_ __\ /__ _/   .-` /  /
//         ======`-.____`-.___\_____/___.-`____.-'======
//                            `=---='
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章