题意:
给定长度为
的序列
与序列
,
次操作,操作一共有三种类型。
·
:令
·
:令
·
:询问
{
},
思路:
看完题就可以发现,整道题最关键的地方就是如何处理下取整,而处理下取整问题通常都是转换成余数形式来进行求解,即 。
因此本题也可以进行简化,令 ,因此 ,因此若 ,则 ,否则为 。
由于 的范围只有 ,因此我们可以对于每一个 ,求出 的累加值,并且维护一个数组 , 表示 mod 的个数。然后二分 ,每次暴力计算前 个 的贡献,即可完成此题。
每次更新 时,暴力维护 数组即可。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 1e5+100;
const int M = 1000+10;
const db EPS = 1e-9;
using namespace std;
int n,a[N],m;
ll b[N],cnt[M][M],num[M],ctt[M];
//cnt[x][y]: 表示ai = x, bi%ai <= y 有多少个
//ctt[x]: 表示ai = x, bi/ai的累加
int main()
{
int _; scanf("%d",&_);
while(_--)
{
memset(cnt,0,sizeof cnt);
memset(num,0,sizeof num);
memset(ctt,0,sizeof ctt);
scanf("%d%d",&n,&m);
rep(i,1,n){
scanf("%d",&a[i]);
num[a[i]]++;
}
rep(i,1,n){
scanf("%lld",&b[i]);
ctt[a[i]] += b[i]/a[i];
rep(j,b[i]%a[i],a[i]-1) cnt[a[i]][j]++;
}
rep(i,1,m){
int op,x; ll k,y;
scanf("%d",&op);
if(op == 1){
scanf("%d%lld",&x,&y);
ctt[a[x]] -= b[x]/a[x];
ctt[y] += b[x]/y;
num[a[x]]--, num[y]++;
rep(j,b[x]%a[x],a[x]-1) cnt[a[x]][j]--;
a[x] = y;
rep(j,b[x]%a[x],a[x]-1) cnt[a[x]][j]++;
}
else if(op == 2){
scanf("%d%lld",&x,&y);
ctt[a[x]] -= b[x]/a[x];
ctt[a[x]] += y/a[x];
rep(j,b[x]%a[x],a[x]-1) cnt[a[x]][j]--;
b[x] = y;
rep(j,b[x]%a[x],a[x]-1) cnt[a[x]][j]++;
}
else{
scanf("%lld",&k);
ll l = 1, r = 1e12, ans;
while(l <= r){
ll mid = (l+r)>>1;
ll tp = 0;
rep(i,0,1000)
if(num[i]){
tp += (ll)(mid/i)*(ll)num[i]-(ll)ctt[i];
tp -= (ll)cnt[i][i-1]-(ll)cnt[i][mid%i];
}
if(tp >= k) ans = mid, r = mid-1;
else l = mid+1;
}
printf("%lld\n",ans);
}
}
}
return 0;
}
/*
2
4 6
2 4 6 8
1 3 5 7
1 2 3
2 3 3
3 15
1 3 8
3 90
3 66
8 5
2 4 8 3 1 3 6 24
2 2 39 28 85 25 98 35
3 67
3 28
3 73
3 724
3 7775
*/