牛客競賽——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
//                        ____/`---'\____
//                      .'  \|     |//  `.
//                     /  \|||  :  |||//  \
//                    /  _||||| -:- |||||-  \
//                    |   | \\  -  /// |   |
//                    | \_|  ''\---/''  |   |
//                    \  .-\__  `-`  ___/-. /
//                  ___`. .'  /--.--\  `. . __
//               ."" '<  `.___\_<|>_/___.'  >'"".
//              | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//              \  \ `-.   \_ __\ /__ _/   .-` /  /
//         ======`-.____`-.___\_____/___.-`____.-'======
//                            `=---='
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//

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