Acwing 106 - 动态中位数
题意: 输出动态中位数。
思路:
对顶堆:
具体思路大致是,开两个堆,一个是大根堆,一个是小根堆,然后小于等于中位数的都放在大根堆,大于等于中位数的都放在小根堆,维护完成之后大根堆堆顶就是动态中位数。
具体维护过程:
- 我们要保证大根堆最大值小于等于小根堆最小值,我们可以通过
if(!down.empty() && x <= down.top()) down.push(x); else up.push(x);
这句话来保证x放入堆之后上述性质成立。 - 我们要保证大根堆大小d和小根堆大小u满足:d>=u && d-u<=1。我们知道放入一个元素之后大小差最大为2,因此if转移即可。
if(down.size() > up.size() + 1) up.push(down.top()), down.pop(); if(up.size() > down.size()) down.push(up.top()), up.pop();
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int ans[N], pos;
int main()
{
int T; scanf("%d", &T);
while(T -- )
{
pos = 0;
int id, n; scanf("%d%d", &id, &n);
priority_queue<int> down;
priority_queue<int, vector<int>, greater<int> > up;
for(int i=0; i < n; i++){
int x; scanf("%d", &x);
if(!down.empty() && x <= down.top()) down.push(x);
else up.push(x);
if(down.size() > up.size() + 1) up.push(down.top()), down.pop();
if(up.size() > down.size()) down.push(up.top()), up.pop();
if(!(i & 1)) ans[pos ++ ] = down.top();
}
printf("%d %d\n", id, (n + 1) / 2);
for(int i=0; i<pos; i++)
if(i && i % 10 == 0) printf("\n%d ", ans[i]);
else printf("%d ", ans[i]);
if(T) printf("\n");
}
system("pause");
return 0;
}
HDU 4699 Editor
题意:
5种操作
I x 光标前插入x这个数
D 删除光标前的数
L 光标左移一位 若已到最左边移不动,就不移
R 光标右移一位 若移不动,就不移了
Q k 输出光标前的序列 从1到k中最大连续序列和
思路: 对顶栈,和对顶堆是一个思路。注意最大前缀和的转移方程 d p [ i ] = m a x ( d p [ i − 1 ] , s u m [ i ] ) dp[i]=max(dp[i-1],sum[i]) dp[i]=max(dp[i−1],sum[i]), d p [ i ] dp[i] dp[i] 表示前 i i i 个前缀的最大值。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int sum[N], dp[N];
void modify(int idx, int x)
{
sum[idx] = sum[idx - 1] + x;
if(idx == 1) dp[1] = x;
else dp[idx] = max(sum[idx], dp[idx - 1]);
}
int main()
{
int T;
while(scanf("%d", &T) != EOF)
{
stack<int>down, up;
while(T -- ){
char op; scanf(" %c", &op);
int x;
if(op == 'I' || op == 'Q') scanf("%d", &x);
if(op == 'I') down.push(x), modify(down.size(), x);
if(op == 'D' && !down.empty()) down.pop();
if(op == 'L' && !down.empty()) up.push(down.top()), down.pop();
if(op == 'R' && !up.empty()) down.push(up.top()), up.pop(), modify(down.size(), down.top());
if(op == 'Q') printf("%d\n", dp[x]);
}
}
system("pause");
return 0;
}