问题 K: Master of Sequence
时间限制: 10 Sec 内存限制: 128 MB
提交: 106 解决: 38
[提交] [状态] [命题人:admin]
题目描述
There are two sequences a1,a2,...,an , b1,b2,...,bn . Let . There are m operations within three kinds as following:
• 1 x y: change value ax to y.
• 2 x y: change value bx to y.
• 3 k: ask min{t|k≤S(t)}
输入
The first line contains a integer T (1≤T≤5) representing the number of test cases.
For each test case, the first line contains two integers n (1≤n≤100000), m (1≤m≤10000).
The following line contains n integers representing the sequence a1,a2,...,an .
The following line contains n integers representing the sequence b1,b2,...,bn .
The following m lines, each line contains two or three integers representing an operation mentioned above.
It is guaranteed that, at any time, we have 1≤ai≤1000, 1≤bi,k≤109 . And the number of queries (type 3 operation) in each test case will not exceed 1000.
输出
For each query operation (type 3 operation), print the answer in one line.
样例输入
复制样例数据
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
样例输出
17
87
65
72
58
74
310
2875
对于原式子 ,令
,
,则原式子可以化为
当 时,值为
当 时,值为
,对于这种情况,向下取整会多算1,所以减去这种情况就可以了
那么,数组b a都是固定的,可以先处理出所有的
式子就变成了 ,式子是单调变化的
二分check时 t 确定,就可以直接计算了
a的范围到1000,那么就可以直接预处理
用一个二维数组f[ i ][ j ] 表示当a==i时,b%a >= j的情况有多少种
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 100;
const int inf = 1e9;
const int mod = 998244353;
int a[maxn], b[maxn];
int f[1100][1100];
bool check(ll t, ll x) {
ll res = 0;
for (int i = 1; i <= 1000; i++) {
res += t / i * f[i][0];
res -= f[i][t % i + 1]; //减去c1<c2的情况
}
return res >= x;
}
ll sol(ll x) {
ll l = 0, r = 1e13;
ll ans = 0;
while (l <= r) {
ll mid = (l + r) >> 1;
if (check(mid, x)) {
ans = mid;
r = mid - 1;
} else l = mid + 1;
}
return ans;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
ll ret = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
ret += b[i] / a[i]; //ret就是k2
f[a[i]][b[i] % a[i]]++;
}
for (int i = 1; i < 1005; i++) {
for (int j = i - 1; j >= 0; j--) {
f[i][j] += f[i][j + 1];
}
}
int p, x, y;
while (m--) {
scanf("%d", &p);
if (p == 1) {
scanf("%d%d", &x, &y);
ret -= b[x] / a[x];
ret += b[x] / y;
for (int i = b[x] % a[x]; i >= 0; i--)
f[a[x]][i]--;
for (int i = b[x] % y; i >= 0; i--)
f[y][i]++;
a[x] = y;
} else if (p == 2) {
scanf("%d%d", &x, &y);
ret -= b[x] / a[x];
ret += y / a[x];
for (int i = b[x] % a[x]; i >= 0; i--)
f[a[x]][i]--;
for (int i = y % a[x]; i >= 0; i--)
f[a[x]][i]++;
b[x] = y;
} else {
ll k;
scanf("%lld", &k);
printf("%lld\n", sol(ret + k));
}
}
memset(f, 0, sizeof(f));
}
return 0;
}