洛谷1314

这道题真的是跟我1314.。。。调了好久

思想:二分查找w,对于每一个枚举的w,都用数组pre[i] num[i]记录前i想满足条件的价值和、数量和。

#include <bits/stdc++.h>
using namespace std;
#define ll long long 
const int maxn=200000+10;
struct Node{
	ll w,v;
}node[maxn];
int n,m;
ll S;
int part[2][maxn];
ll val[maxn];
int num[maxn];


ll f(int x)//如果x1和x2都满足
{
	 ll sum=0;
	 ll temp;
	 int i,j;
	 val[0]=num[0]=0;
	 for(i=1;i<=n;i++){
	 	if(node[i].w>=x) val[i]=val[i-1]+node[i].v,num[i]=num[i-1]+1;
		else val[i]=val[i-1],num[i]=num[i-1];
	 }
	 for(i=0;i<m;i++){
	 	int l=part[0][i],r=part[1][i];
	 	temp=(num[r]-num[l-1])*(val[r]-val[l-1]);
		sum+=temp;
	}
	return sum-S;
}
int main()
{
	int i,j,k;
	cin >> n >> m >> S;
	ll Max_W=0;
	for(i=1;i<=n;i++){
		scanf("%lld %lld",&node[i].w,&node[i].v);
		Max_W=max(Max_W,node[i].w);
	}
	for(i=0;i<m;i++)
		scanf("%d %d",&part[0][i],&part[1][i]);
	int w1=0,w2=Max_W;
	ll sum1=f(w1),sum2=f(w2);
	while(w1<w2)
	{
		int mod=(w1+w2)>>1;
		if(mod!=w1) sum2=f(mod);
		else{
			sum2=f(w2);
			break;
		}
		if(0==sum1||0==sum2)
			break;
		else if(sum1<0&&sum2>0 || sum1>0&&sum2<0)
			w2=mod;
		else{
			w1=mod;
			sum1=sum2;
		}
	}
	if(sum1<0) sum1=-sum1;
	if(sum2<0) sum2=-sum2; 
	printf("%lld\n",(ll)min(sum1,sum2));
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值