Input示例 9 11 1 2 0 4 3 2 1 5 7 2 8 0 7 6 5 3 4 5 6 5 Output示例 2 2 2 4 3 3 5 6 7
思路:刚开始以为结点存最大值就行了,然后大于左子树的最大值就能进入右子树;然后发现样例都过不了;后面发现,并不是这个样子,假如这个数小于等于右孩子最左边那个数的话,也不能进入有孩子,所以结点还得保存右孩子最左边的那个值;同时更新一个最大值,当输入值咸鱼等于a[0]或者大于最大值时跳过。
#include<climits> #include<iostream> #include<algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define ll long long const int maxn = 5e4 + 5; ll tree[maxn << 2], mtree[maxn << 2], a[maxn]; ll ma = INT_MIN; void build(int l, int r, int rt) { if (l == r){ tree[rt] = a[l]; mtree[rt] = a[l]; return; } int m = (l + r) >> 1; build(lson); build(rson); tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]); mtree[rt] = mtree[rt << 1]; } void update(int x, int l, int r, int rt) { if (l == r){ a[l] += 1; tree[rt] += 1; mtree[rt] += 1; if (a[l] > ma)ma = a[l]; return; } int m = (l + r) >> 1; if (tree[rt << 1] < x&&x>mtree[rt << 1 | 1]) update(x, rson); else update(x, lson); tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]); mtree[rt] = mtree[rt << 1]; } void Print(int l, int r, int rt) { if (l == r){ cout << rt << " = " << tree[rt] << endl; return; } cout << rt << " = " << tree[rt] << endl; int m = (r + l) >> 1; if (l <= m)Print(lson); if (r > m)Print(rson); } int main() { std::ios::sync_with_stdio(false); int m, n; cin >> m >> n; for (int i = 1; i <= m; i++){ cin >> a[i]; if (ma < a[i])ma = a[i]; } build(1, m, 1); int temp; while (n--){ cin >> temp; if (temp <= a[1] || temp>ma) continue; update(temp, 1, m, 1); //Print(1, m, 1); } for (int i = 1; i <= m; i++){ if (i != 1)cout << endl; cout << a[i]; } }