题目描述
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
思路
面对需要更改值,并需要求区间和的序列,可以用树状数组来维护求值,这题要求最小值,可以用二分法寻找答案
具体推理可见:
HDU 6274 Master of sequence(二分答案 + 树状数组)
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <string>
#include <cstdlib>
#include <cstring>
#include <map>
#include <set>
#include <stack>
#include <cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int N=1005;
const int M=100005;
int T,n,m;
int a[M],b[M],t[M];
int lowbit(int x)
{
return x&(-x);
}
struct BinaryIndexTree
{
int c[N];
inline void update(int x,int y)
{
x++;
for(int i=x;i<N;i+=lowbit(i)) c[i]+=y;
}
inline int getsum(int x)
{
int res=0;
x++;
for(int i=x;i;i-=lowbit(i)) res+=c[i];
return res;
}
}BIT[N];
bool check(ll x,ll y)
{
ll s=0;
for(int i=1;i<=1000;i++)
{
s+=(x/i)*t[i]-(t[i]-BIT[i].getsum(x%i));
if(s>=y+1000-i) return true;
}
return s>=y;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
ll s=0;
memset(t,0,sizeof(t));
memset(BIT,0,sizeof(BIT));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
t[a[i]]++;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
s+=b[i]/a[i];
BIT[a[i]].update(b[i]%a[i],1);
}
while(m--)
{
ll ans;
int op,x,y;
scanf("%d",&op);
if(op==1)
{
scanf("%d%d",&x,&y);
s=s-b[x]/a[x]+b[x]/y;
t[a[x]]--;
BIT[a[x]].update(b[x]%a[x],-1);
BIT[y].update(b[x]%y,1);
a[x]=y;
t[y]++;
}
if(op==2)
{
scanf("%d%d",&x,&y);
s=s-b[x]/a[x]+y/a[x];
BIT[a[x]].update(b[x]%a[x],-1);
BIT[a[x]].update(y%a[x],1);
b[x]=y;
}
if(op==3)
{
scanf("%d",&x);
ll xx=x+s;
ll l=0,r=2e12,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid,xx))
{
ans=mid;
r=mid-1;
}
else l=mid+1;
}
printf("%lld\n",ans);
}
}
}
return 0;
}