题目描述
某天cbyyx突发奇想给lyt出了一道题:给定序列a,b,保证|a|+|b|为奇数且小于1e6,给定q组询问,每次将a序列其中一个数修改或将b序列其中一个数修改,问每次操作后两序列合并后的中位数是多少,lyt觉得这个问题太简单并把它秒了,但lyt觉得这个题对新生来说有点困难,于是他简化问题如下:给定两个正整数n,m,再给定长度为n的正整数序列a, 保证n为奇数。接下来m行,每行两个正整数p, x。表示把a[p]修改为x。对于每次操作输出修改后的中位数。
输入描述:
第一行输入两个正整数n,m
第二行给定n个正整数表示序列a1a_{1}a1~ana_{n}an
接下来m行每行给定两个数p,x,表示将a[p]修改为x。
1<=n<=1e6,1<=m<=1e5
∀1<=i<=n,1<=ai<=1e6\forall1<=i<=n,1<=a_{i}<=1e6∀1<=i<=n,1<=ai<=1e6
1<=x<=1e6
输出描述:
对于每次操作输出每次操作后序列的中位数的值。
示例1
输入
7 3 1 2 3 4 5 6 7 2 3 4 4 7 1
输出
4 4 3
中位数原来可以用树状数组来求!!!!受教了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int M=4e4+10;
const int N=1e6+10;
const int INF=0x3f3f3f3f;
int minn=0x3f3f3f3f;
int maxn=0xc0c0c0c0;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int n,k,m;
int a[N],tr[N];
int lowbit(int x)
{
return x&-x;
}
void add(int x,int y)
{
for(int i=x;i<=N;i+=lowbit(i)) tr[i]+=y;
}
int sum(int x)
{
int res=0;
for(int i=x;i;i-=lowbit(i)) res+=tr[i];
return res;
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
add(a[i],1);
}
int c=n/2+n%2;
for(int i=0,p,x;i<m;i++)
{
cin>>p>>x;
add(a[p],-1);
add(a[p]=x,1);
int l=1,r=1e6;
while(l<r)
{
int mid=l+r>>1;
int v=sum(mid);
if(v>=c) r=mid;
else l=mid+1;
}
cout<<l<<endl;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
ll t=1;
// cin>>t;
while(t--)
{
solve();
}
return 0;
}