题目链接:http://47.93.252.151/problem.php?id=1157
有序表直接删除第一个数输出中间就行
树状数组维护的是一个和加上一个二分(多看书 lydnb 感谢lyd给我灵感2333)
有序表代码:
#include <bits/stdc++.h>
typedef int ll;
using namespace std;
const ll maxn = 1e5 + 7;
ll b[maxn];
vector<ll>a;
int main()
{
// ios::sync_with_stdio(0);
// cin.tie(0),cout.tie(0);
ll n,x,m,to;
cin >> n >> m;
for(int i = 1; i <= n; i ++)
{
cin >> b[i];
}
for(int i = 1; i <= n; i ++)
{
a.insert(lower_bound(a.begin(),a.end(),b[i]),b[i]);
if(i >= m)
{
cout << a[a.size() / 2] << " ";
a.erase(lower_bound(a.begin(),a.end(),b[i - m + 1]));
}
}
return 0;
}
树状数组代码
#include <bits/stdc++.h>
#define endl '\n'
#define gcd __gcd
using namespace std;
typedef long long ll;
typedef long double ld;
const ll maxn = 1e5 + 7;
const ll mod = 1e9 + 7;
ll n,c[maxn],m,a[maxn];
ll lowbit(ll x)
{
return x & -x;
}
void update(ll x,ll y)
{
for(int i = x; i <= n; i += lowbit(i))
{
c[i] += y;
}
}
ll getsum(ll x)
{
ll ans = 0;
for(int i = x; i > 0; i -= lowbit(i))
{
ans += c[i];
}
return ans;
}
ll check(ll x)
{
ll l = 1,r = n,p;
while(l <= r)
{
ll mid = (l + r) / 2;
if(getsum(mid) >= x)
{
p = mid;
r = mid - 1;
}
else
{
l = mid + 1;
}
}
return p;
}
int main()
{
//ios::sync_with_stdio(0);
//cin.tie(0),cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
}
for(int i = 1; i <= m; i ++)
{
update(a[i],1);
}
cout << check(m / 2 + 1) << ' ';
for(int i = m + 1; i <= n; i ++)
{
update(a[i - m],-1);
update(a[i],1);
cout << check(m / 2 + 1) << ' ';
}
cout << endl;
return 0;
}