题意:
现在有n个东西,每个东西价值ai元,现在有m个人,每个人都有bi元,每个人都会按顺序买自己能买的并且最贵的东西,现在有q个操作
1 x y 表示将第x个物品的价值变成y
2 x y 表示第x个人拥有的钱变成y
每次操作结束后问你你现在能买的最贵的东西的价值是多少
题解:
和上次一道题目很像,转化到线段树里就变成了一个前缀的问题,物品的价值变成1-ai 的位置+1,这个人bi表示为1-bi的位置-1,这样消去的必然是小于等于bi位置较大的那个数的影响。然后查询值>=1的位置最大是多少即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int mx[N*4],flag[N*4];
void push_down(int root)
{
if(!flag[root])
return ;
mx[root<<1]+=flag[root];
mx[root<<1|1]+=flag[root];
flag[root<<1]+=flag[root];
flag[root<<1|1]+=flag[root];
flag[root]=0;
}
void update(int l,int r,int root,int ql,int qr,int v)
{
if(l>=ql&&r<=qr)
{
mx[root]+=v;
flag[root]+=v;
return ;
}
int mid=l+r>>1;
push_down(root);
if(mid>=ql)
update(l,mid,root<<1,ql,qr,v);
if(mid<qr)
update(mid+1,r,root<<1|1,ql,qr,v);
mx[root]=max(mx[root<<1],mx[root<<1|1]);
}
int query(int l,int r,int root)
{
if(mx[root]<=0)
return -1;
if(l==r)
return l;
push_down(root);
int mid=l+r>>1;
if(mx[root<<1|1]>0)
return query(mid+1,r,root<<1|1);
return query(l,mid,root<<1);
}
int a[N],b[N];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),update(1,1e6,1,1,a[i],1);
for(int i=1;i<=m;i++)
scanf("%d",&b[i]),update(1,1e6,1,1,b[i],-1);
int q;
scanf("%d",&q);
while(q--)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
update(1,1e6,1,1,a[x],-1);
update(1,1e6,1,1,y,1);
a[x]=y;
}
else
{
update(1,1e6,1,1,b[x],1);
update(1,1e6,1,1,y,-1);
b[x]=y;
}
printf("%d\n",query(1,1e6,1));
}
return 0;
}