Hdu 6274(预处理+二分)

1、题面:

2、思路:

因为ai的范围是1~1000,所以可以遍历所有1~1000的值,

所以将t,bi拆分为t = k1*ai+c1 , bi = k2*ai+c2.

得到k1,c1,k2,c2均为0~1000范围内,将不等式化简。

详情见此图

推导在图中,因为c1 = t%ai,c2 = bi%ai

而且因为向下取整,只考虑c1-c2<0的情况即可。

所以可以预处理这部分值,设定数组sum[x][y]表示ai = x,所有满足bi%ai>=y的情况。

这样求图中不等式右边部分时只要-sum[i][x%i+1](表示减去c1小于c2这部分的值)这部分就行了。

然后每次通过二分求解求得t的最小值。

3、代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1005;
const int N = 1e5+10;
const LL INF = 1e13+10;
int sum[maxn][maxn],a[N],b[N],n,m;
bool pd(LL x,LL y){
	LL res = 0;
	for(int i=1;i<=1000;i++){
		res += x/i*sum[i][0];
		res -= sum[i][x%i+1];
	}
	return res>=y;
}
LL cal(LL x){
	LL l = 1,r = INF;
	while(l<=r){
		LL mid = (l+r)>>1LL;
		if(pd(mid,x)==true) r = mid-1;
		else l = mid+1;
	}
	return l;
}
int main(void){
	int T;
	scanf("%d",&T);
	while(T--){
		memset(sum,0,sizeof(sum));
		LL k = 0;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		for(int i=1;i<=n;i++){
			scanf("%d",&b[i]);
			sum[a[i]][b[i]%a[i]]++;
			k += b[i]/a[i];
		}
		for(int i=1;i<=1000;i++){
			for(int j=i-1;j>=0;j--){
				sum[i][j] += sum[i][j+1];
			}
		}
		while(m--){
			int op,x,y;
			scanf("%d",&op);
			if(op==1){
				scanf("%d%d",&x,&y);
				k -= b[x]/a[x];
				k += b[x]/y;
				for(int i=b[x]%a[x];i>=0;i--)
					sum[a[x]][i]--;
				for(int i=b[x]%y;i>=0;i--)
					sum[y][i]++;
				a[x] = y;
			}
			else if(op==2){
				scanf("%d%d",&x,&y);
				k -= b[x]/a[x];
				k += y/a[x];
				for(int i=b[x]%a[x];i>=0;i--) 
					sum[a[x]][i]--;
				for(int i=y%a[x];i>=0;i--)
					sum[a[x]][i]++;
				b[x] = y;
			}
			else{
				scanf("%d",&x);
				printf("%lld\n",cal(x+k));
			}
		}
	}
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值