杭电多校第三次 Problem A. Ascending Rating(单调队列)

本文介绍了一种使用单调队列实现滑动窗口算法的方法,该算法可以高效地求解给定数组中长度为m的子数组的最大值及其更新次数。通过从后往前滑动窗口,并利用单调队列维护子数组中的最大值,使得问题得以解决。

【题意】
给你一个长为n的数组a
让你对于每个长度为m的窗口。
算出其中的最大值以及从左往右遍历的时候这个最大值更新的次数。
【题解】
单调队列。
从后往前滑动窗口。
会发现我们维护以这个窗口里面的值为元素的单调队列的时候。
这个单调队列的长度就是最大值更新的次数。
因为我们把a[i]加入队列的时候。
队列尾巴上,小于等于这个a[i]的元素都会被删掉.
每个都这么做的话。
队列里面的元素就和更新时候的元素对应。
最大值就是队列的头部。


#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define pii pair<ll,ll>
using namespace std;
const int maxn=10000005;
ll nex[maxn],a[maxn],qq[maxn],t;
ll p,q,r,mo,ans,cnt,j,ctt,n,m,k,i,ma,ct,kk;
int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        i=1;
        scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&k,&p,&q,&r,&mo);
        while(i<=n)
        {
            if(i<=k) scanf("%lld",&a[i]);
            else a[i]=(p*a[i-1]+q*i+r)%mo;
            i++;
        }
        ans=cnt=0;
        for(ll h=1,t=0,i=n;i;i--)
        {
            while(h<=t&&a[qq[t]]<=a[i]) t--;
            qq[++t]=i;
            if(i<=n-m+1)
            {
                while(qq[h]>=i+m) h++;
                ans+=(i^a[qq[h]]);
                cnt+=(i^(t-h+1));
            }
        }
        printf("%lld %lld\n",ans,cnt);
    }
    return 0;
}
✅ **你遇到了一个常见但关键的 Qt 行为陷阱:** > 即使你调用了 `header.setSortIndicator(0, Qt.AscendingOrder)`,**如果用户曾经点击过第二列触发排序,Qt 的 QHeaderView 可能会“记住”其他列的状态或样式残留**,导致视觉上第二列仍然显示箭头。 但这通常不是因为 `setSortIndicator()` 失效,而是由以下原因造成: --- ### 🔍 问题分析:为什么第二列还显示箭头? #### ✅ 正确理解: - `QHeaderView` 在启用排序后,**同一时间只能有一个列显示排序箭头**(默认行为); - 调用 `setSortIndicator(0, order)` 应该自动隐藏之前列(如第1列)的箭头; - ❌ 如果第二列仍有箭头 → 很可能是 **样式未刷新、事件未处理、或列被重新激活**。 --- ### ✅ 正确解决方案 #### ✔️ 方法一:使用 `sortByColumn()` 替代手动设置指示器(推荐) ```python tableView.setSortingEnabled(True) tableView.sortByColumn(0, Qt.AscendingOrder) # 自动清除其他列箭头 ``` 👉 这是最标准做法。`sortByColumn()` 不仅排序数据,还会: - 调用模型的 `.sort(0, order)` - 设置正确的排序列 - ✅ **自动移除其他列的排序指示器** > ⚠️ 不要只调用 `setSortIndicator()`,否则可能只改 UI 不改数据,且无法保证旧箭头被清除。 --- #### ✔️ 方法二:确保没有外部干扰 —— 禁用非目标列的可点击性 有时候,即使你设置了第0列排序,但如果用户之前点击了第1列,或者代码中某处又触发了它,就会出现“双箭头”假象。 ✅ 解决方法:禁用不需要排序的列的点击功能 ```python header = tableView.horizontalHeader() header.setSectionsClickable(False) # 全局禁止点击表头排序 # 或者只允许第0列可点击 for col in range(header.count()): if col != 0: header.setSectionResizeable(col, True) # 保持可调整大小 header.setSectionsClickable(col, False) ``` 这样就能防止用户误点第二列导致其获得排序焦点。 --- #### ✔️ 方法三:强制刷新表头状态(解决样式残留) 有时是 **渲染缓存或样式表未更新** 导致视觉残留。 可以尝试强制重绘表头: ```python tableView.sortByColumn(0, Qt.AscendingOrder) tableView.horizontalHeader().update() # 强制刷新 UI ``` 或者在设置后稍等一下再刷新(适用于延迟场景): ```python from PySide6.QtCore import QTimer tableView.sortByColumn(0, Qt.AscendingOrder) QTimer.singleShot(0, tableView.horizontalHeader().update) ``` --- #### ✔️ 方法四:检查是否启用了自定义样式表(CSS) 如果你设置了类似这样的样式: ```python tableView.setStyleSheet(""" QHeaderView::down-arrow { image: url(down.png); } QHeaderView::up-arrow { image: url(up.png); } """) ``` 而没有正确管理个列的箭头逻辑,可能导致个列同时显示箭头(尤其是手动操作不当)。 ✅ 修复方式:使用标准行为,避免复杂 CSS 控制箭头。 --- ### 🧪 验证是否真有“两个箭头” 你可以添加调试输出来确认当前排序列: ```python header = tableView.horizontalHeader() print("Current sort indicator section:", header.sortIndicatorSection()) print("Current sort order:", "Asc" if header.sortIndicatorOrder() == Qt.AscendingOrder else "Desc") ``` 👉 如果输出是 `0`,说明只有第0列应该是有箭头的。 如果第1列仍显示箭头 → 是 **UI 渲染异常或样式残留**。 --- ### ✅ 总结:如何确保只有第一列显示排序箭头? ```python # 完整可靠的做法 tableView.setSortingEnabled(True) # 真正触发排序并设置箭头 tableView.sortByColumn(0, Qt.AscendingOrder) # 禁止其他列响应点击 header = tableView.horizontalHeader() for col in range(1, header.count()): header.setSectionClickable(col, False) # (可选)强制刷新 UI header.update() ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值