[CF 61E]Enermy is weak[线段树求二重逆序数]

本文介绍了一种利用线段树求解单调下降三元组数量的方法。通过两次求解逆序数的方式,先求解每个元素的逆序数,再求解这些逆序数构成序列的逆序数,最终得到所有可能的单调下降三元组的数量。

题意:

求单调下降的三元组的个数. 三个元素不一定要连续.

思路:

转化为求二重逆序数:

线段树求出逆序数, 再求逆序数序列的逆序数.

#include <cstdio>
#include <algorithm>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
typedef long long ll;
const int maxn = 1000005;
ll sum[maxn<<2];
typedef struct stru{
    int id;
    int val;
}stru;
stru  x[maxn];
int rev[maxn];
bool cmpid(stru a,stru b)
{
    return a.id < b.id;
}
bool cmpval(stru a,stru b)
{
    return a.val < b.val;
}

void PushUP(int rt)
{
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void build(int l,int r,int rt)
{
    sum[rt] = 0;
    if (l == r) return ;
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
}

void update(int p,int l,int r,int rt)
{
    if (l == r)
    {
        sum[rt] ++;
        return ;
    }//更新的方法是在p位置上加1,于是向上的节点依次加1
    int m = (l + r) >> 1;
    if (p <= m) update(p , lson);
    else update(p , rson);
    PushUP(rt);
}

void updaterev(int id,int p,int l,int r,int rt)
{
    if (l == r)
    {
        sum[rt] = rev[id];
        //printf("x[%d] %d rev[%d] %I64d\n",id,x[id],id,rev[id]);
        return ;
    }//更新的方法是在p位置上加1,于是向上的节点依次加1
    int m = (l + r) >> 1;
    if (p <= m) updaterev(id, p , lson);
    else updaterev(id, p , rson);
    PushUP(rt);
}

ll query(int L,int R,int l,int r,int rt)
{
    if (L <= l && r <= R)
    {
        return sum[rt];
    }
    int m = (l + r) >> 1;
    ll ret = 0;
    if (L <= m) ret += query(L , R , lson);
    if (R > m) ret += query(L , R , rson);
    return ret;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x[i].val);
        x[i].id = i;
    }
    sort(x,x+n,cmpval);
    for(int i=0;i<n;i++)    x[i].val = i;
    sort(x,x+n,cmpid);
    build(0 , n-1 , 1);
    for (int i = 0; i < n; i ++)
    {
///算法:将元素依次插入线段树,每个数的逆序对数为比它大的已经插入的数的个数
        rev[i] = query(x[i].val+1 , n-1 , 0 , n-1 , 1);///每个数的逆序数
        update(x[i].val , 0 , n-1 , 1);
    }
    ///需要求比x[i]大的数的逆序数之和!!!
    ll ans = 0;
    build(0, n-1, 1);
    for(int i=0;i<n;i++)
    {
        ans += query(x[i].val+1 , n-1 , 0, n-1 , 1);///已经插入的数的逆序数之和
        updaterev(i, x[i].val , 0, n-1 , 1);
    }
    printf("%I64d\n",ans);

    return 0;
}


<think>We are given a warning: "Instance will be immediately deallocated because property 'messageCenterController' is 'weak'" This happens because we assign a newly created instance to a weak property and there are no strong references to it. To fix this, we need to hold a strong reference to the newly created controller until we don't need it anymore. In the current code: if self.messageCenterController == nil { self.messageCenterController = MessageCenterController() // This new instance is only held by a weak reference? -> will be deallocated immediately } We need to have at least one strong reference. We can do this by: Option 1: Change the property to strong (remove weak) but then we must be cautious of retain cycles. Option 2: Keep a strong reference in the parent controller (e.g., by storing it as a child view controller). Since the messageCenterController is a view controller that we are going to add as a subview (its view) to the window's contentView, we should also manage it as a child view controller to ensure proper lifecycle events. Let's revise the code: 1. Change the property to strong (if we don't use child view controller) OR 2. Use child view controller to hold a strong reference. Recommended approach: Use child view controller. Steps for adding as child view controller: - When creating the messageCenterController, add it as a child to the current view controller. - Then add its view to the hierarchy. - When removing, remove the view and then remove from parent. However, note that we are adding the view to the window's contentView, which might not be the same as the view controller's view. But still, we can manage the controller by adding it as a child. Revised code for the callback: ```swift class MainViewController: UIViewController { // Change to strong reference because we are going to manage it as a child view controller. private var messageCenterController: MessageCenterController? func setupToolbar() { toolBar.messageCenterButtonClickedCallBack = { [weak self] button in guard let self = self else { return } print("展开消息中心") if self.messageCenterController == nil { // Create the controller let messageCenterVC = MessageCenterController() self.messageCenterController = messageCenterVC // Add as child view controller self.addChild(messageCenterVC) messageCenterVC.didMove(toParent: self) print("首次创建消息中心控制器") } guard let messageCenterVC = self.messageCenterController else { return } let visible = messageCenterVC.isVisible if !visible { // Show if let contentView = self.view.window?.contentView { messageCenterVC.changeVisible() // Update state to visible // We already have the view, but it might be hidden. Show it by setting isHidden = false or add if not added. if messageCenterVC.view.superview == nil { contentView.addSubview(messageCenterVC.view) messageCenterVC.view.snp.makeConstraints { make in make.top.equalToSuperview().offset(56) make.trailing.equalToSuperview() make.bottom.equalToSuperview() make.width.equalTo(468) } } messageCenterVC.view.isHidden = false } print("++++++++关闭的,现在开启+++++++++++++") } else { // Hide messageCenterVC.changeVisible() // Update state to hidden messageCenterVC.hideAll() // This sets view.isHidden = true print("++++++++开启的,现在关闭+++++++++++++") self.messagePopover?.dismiss() } } } } ``` ### Explanation of changes: 1. **Property Declaration**: - Changed `messageCenterController` from weak to strong (`private var`). 2. **Child View Controller Management**: - When creating the controller, we add it as a child: ```swift self.addChild(messageCenterVC) messageCenterVC.didMove(toParent: self) ``` - This establishes a strong reference and ensures proper lifecycle events. 3. **View Management**: - We check if the view is already added (`if messageCenterVC.view.superview == nil`). If not, we add it and set constraints. - When showing, we set `isHidden = false` (if already added but hidden). - When hiding, we set `isHidden = true` (via `hideAll`). 4. **Hiding**: - The `hideAll` method in `MessageCenterController` should set `view.isHidden = true` and update `isVisible`. ### Additional Note: - The `hideAll` method in `MessageCenterController` can be simplified to: ```swift func hideAll() { isVisible = false view.isHidden = true } ``` - The `changeVisible` method can be removed if we are using `hideAll` for hiding and setting `isHidden = false` for showing. Alternatively, we can keep it for toggling. ### Why this fixes the warning? - By holding a strong reference (via the parent-child relationship) we prevent the immediate deallocation. - The child view controller will be retained by the parent until the parent is deallocated or we remove it. §§相关问题§§ 1. Swift中weak属性导致对象立即释放的常见场景有哪些? 2. 如何正确使用addChild和didMove(toParent:)来管理子视图控制器? 3. 在什么情况下需要手动移除子视图控制器?如何进行移除? 4. 使用SnapKit设置约束时,如何避免多次添加相同的约束? 5. 当将一个视图控制器的视图添加到另一个视图控制器的视图层级时,生命周期方法如何调用? </think>在 Swift 中,当您看到一个警告 "Instance will be immediately deallocated because property 'messageCenterController' is 'weak'",这是因为您将新创建的控制器实例赋值给了一个 weak 属性。weak 引用不会增加对象的引用计数,导致新创建的对象会立即被释放。 ### 问题分析和解决方案: ```swift // 错误示例 private weak var messageCenterController: MessageCenterController? func setupToolbar() { toolBar.messageCenterButtonClickedCallBack = { [weak self] button in if self?.messageCenterController == nil { // 这里创建的对象会立即被释放 self?.messageCenterController = MessageCenterController() } } } ``` ### 正确实现: ```swift class MainViewController: UIViewController { // 改为强引用 private var messageCenterController: MessageCenterController? func setupToolbar() { toolBar.messageCenterButtonClickedCallBack = { [weak self] button in guard let self = self else { return } // 检查是否已有实例 if self.messageCenterController == nil { // 创建并保持强引用 self.messageCenterController = MessageCenterController() // 添加为子控制器(可选但推荐) self.addChild(self.messageCenterController!) self.messageCenterController?.didMove(toParent: self) } // 后续操作... } } } ``` ### 关键修改说明: 1. **引用类型修改**: - 将 `weak var` 改为 `var`(强引用) - 确保控制器实例有至少一个强引用持有者 2. **内存管理优化**: - 添加为子控制器 (`addChild` 和 `didMove(toParent:)`) - 父控制器会自动管理子控制器的生命周期 - 在父控制器释放时自动释放子控制器 3. **替代方案**(若不想作为子控制器): ```swift // 在类中添加强引用数组 private var retainedControllers = [UIViewController]() // 创建时添加 if self.messageCenterController == nil { let newController = MessageCenterController() self.messageCenterController = newController self.retainedControllers.append(newController) } ``` ### 完整修正代码: ```swift class MainViewController: UIViewController { private var messageCenterController: MessageCenterController? func setupToolbar() { toolBar.messageCenterButtonClickedCallBack = { [weak self] button in guard let self = self else { return } // 创建或获取控制器 if self.messageCenterController == nil { self.messageCenterController = MessageCenterController() self.addChild(self.messageCenterController!) self.messageCenterController?.didMove(toParent: self) } guard let messageCenterVC = self.messageCenterController else { return } // 显示/隐藏逻辑不变 if !messageCenterVC.isVisible { // 显示操作... } else { // 隐藏操作... } } } // 在适当时候清理 deinit { messageCenterController?.willMove(toParent: nil) messageCenterController?.view.removeFromSuperview() messageCenterController?.removeFromParent() } } ``` ### 为什么需要这样修改? | 引用类型 | 行为 | 是否保留对象 | |---------|------|-------------| | `strong` | 增加引用计数 | ✅ 是 | | `weak` | 不增加引用计数 | ❌ 否(对象立即释放) | | `unowned` | 不增加引用计数 | ❌ 否(危险引用) |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值