Problem A. Ascending Rating HDU - 6319(单调队列)

本文介绍了一种使用单调队列求解区间最大值及比较次数的高效算法,通过正向遍历获取最大值,逆向遍历记录比较次数,避免了传统方法的高时间复杂度。

这里写图片描述
这里写图片描述

题意:

找到1-n中间每个间隔为m的最大值,和获得这个最大值的比较次数,然后按照题目所给公式将每个区间的结果异或i得到最终结果

分析:

首先观察数据我们知道,一定不能跑二次循环,即每个枚举每个区间,然后在每个区间中再遍历比较最大值并记录次数,这样的复杂度是O(mn)的必然超时,因此我们得想到用O(n)的方法来解决这个问题
那么就是单调队列

我们可以从前往后遍历维护一个单调递减队列,队列中存标号,这样我们就可以得每个区间的最大值
例如3 5 7 9
首先3入队
{3}
然后到5,先将3出队,再将5入队
{5}
然后到7,先将5出队,再将7入队
{7}
最后同理7出队,9入队
{9}
所以最大值是9,即队列的最左端元素是最大的

怎么保证这个最左端元素一定在m的间距范围呢

只需要保证最左端的元素下标,应当大于等于i-m+1,如果小于说明在i区间的左侧,就出队,这样也就是记录了第i个区间的最大值了。

但是我们发现按照这种方式,我们只能得到最大值却不能得到次数

这样因为我们希望较大的值进去后就不在出来了,这样就可以记录下区间内最大值的替换过程
只需要倒着遍历维护单调递减区间即可

还是刚才的例子我们倒着遍历其实是遍历
9 7 5 3
这样9先入队,很明显他是最大的,之后不会破坏单调性,也就不会再出来了
{9}
7入队
{9,7}
5入队
{9,7,5}
3入队
{9,7,5,3}
这样我们相当于一共换了3次,就得到了相应区间的交换次数。

code:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 7e7+10;
typedef long long ll;
int arr[maxn],maxval[maxn],que[maxn],num[maxn];
int n,m,k,p,q,r,mod;
void getMax(int n,int k){
    int head = 0,rear = 0;
    for(int i = 1; i <= n; i++){
        while(rear > head && arr[que[rear-1]] <= arr[i]) rear--;
        que[rear++] = i;
        if(i < k) continue;
        while(que[head] < i - k + 1) head++;
        maxval[i] = arr[que[head]];
    }
}
void getNum(int n,int k){
    int head = 0, rear = 0;
    for(int i = n; i >= 1; i--){//倒着遍历
        while(rear > head && arr[que[rear-1]] <= arr[i]) rear--;
        que[rear++] = i;
        if(i > n - k + 1) continue;
        while(que[head] > i + k - 1) head++;//这里因为是倒着遍历的,所以head++坐标会变小,不断这样下去就可以满足范围了
        num[i] = rear - head;
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d%d%d%d%d",&n,&m,&k,&p,&q,&r,&mod);
        for(int i = 1; i <= k; i++){
            scanf("%d",&arr[i]);
        }
        for(int i = k + 1; i <= n; i++){
            arr[i] = ((ll)p % mod * arr[i-1] % mod + (ll)q % mod * i % mod + r % mod) % mod;
        }
        getMax(n,m);
        getNum(n,m);
        ll b = 0, a = 0;
        for(int i = 1; i <= n - m + 1; i++){
            b = b + (num[i] ^ i);
            a = a + (maxval[i+m-1] ^ i);
        }
        printf("%lld %lld\n",a,b);
    }
    return 0;
}
<think> 我们正在使用Element UI(注意不是ElementPlus),要实现表格排序箭头的样式自定义:未点击时为灰色,点击激活排序时变为指定颜色(比如绿色)。 在Element UI中,排序箭头的样式是通过CSS控制的。我们可以通过覆盖默认样式来实现。 实现思路: 1. 默认状态(未激活排序)时,排序箭头为灰色。 2. 当列头被点击激活排序(升序或降序)时,将当前激活的箭头颜色改为指定颜色(如绿色),而另一个箭头保持灰色(或隐藏,根据Element UI的默认行为,激活排序时只显示一个箭头)。 注意:Element UI中,排序激活时,会为表头单元格添加以下类: - 升序激活:`.ascending` - 降序激活:`.descending` - 同时,还会添加`.sorting`类(表示正在排序)或者`.active`类(表示激活)?实际上,Element UI中激活排序的列头会有`.ascending`或`.descending`,并且会有一个表示激活状态的类(在Element UI 2.x中,激活的列头会有一个`color`和`font-weight`的变化,但箭头颜色是通过边框色控制的)。 具体到箭头图标,Element UI使用伪元素来绘制三角形箭头。在未排序时,两个箭头(上、下)都是灰色;当升序排序时,上箭头变成激活色(同时下箭头隐藏?实际上是消失,因为只显示一个箭头);降序同理。 但实际上,在Element UI中,排序状态是通过两个伪元素(上箭头和下箭头)的边框颜色来控制的。默认情况下,两个箭头都是灰色。当激活排序时,其中一个箭头会变成主题色(蓝色),另一个则透明。 现在我们要把激活状态的主题色改成绿色,并且默认状态改成灰色。 关键点:覆盖箭头边框颜色。 默认样式(Element UI原始样式): - 未激活:两个箭头都是灰色(#c0c4cc) - 激活:升序时上箭头为蓝色,降序时下箭头为蓝色 修改目标: - 未激活:两个箭头都为灰色(#c0c4cc) - 激活:升序时上箭头为绿色(#67c23a),降序时下箭头为绿色(#67c23a) 具体步骤: 1. 覆盖未激活状态的箭头颜色为灰色(注意,原始未激活状态已经是灰色,但如果主题被修改过,可能需要覆盖)。 2. 覆盖激活状态的箭头颜色为绿色。 但是,在Element UI中,激活排序时,另一个箭头会被隐藏(通过设置透明)。所以我们要确保激活时只改变当前激活的箭头颜色。 覆盖样式(注意选择器的优先级): - 未激活状态:选择器 `.el-table .caret-wrapper .sort-caret` - 激活状态:选择器 `.el-table .caret-wrapper .ascending`(升序箭头)和 `.el-table .caret-wrapper .descending`(降序箭头) 具体CSS代码: ```css /* 默认状态(未激活)的排序箭头颜色 */ .el-table .caret-wrapper .sort-caret { border-bottom-color: #c0c4cc; /* 下箭头(即升序箭头)的边框色 */ } .el-table .caret-wrapper .sort-caret.ascending { border-bottom-color: #c0c4cc; /* 上箭头(即降序箭头)的边框色 - 注意:这里其实是下箭头,因为ascending类对应的伪元素是下边框有颜色,上箭头是通过上边框实现的 */ } /* 注意:Element UI中的排序箭头是一个元素的两个伪元素,类名分别是.ascending(上箭头)和.descending(下箭头)?实际上,在2.x版本中,每个箭头是一个独立的元素(i标签),分别有类名.ascending.descending。所以我们可以分别设置 */ /* 升序激活状态:上箭头(注意在Element UI中升序对应的是下箭头?不,实际上升序对应的是向上的箭头,但DOM结构是:升序箭头(.ascending)显示在上面,降序箭头(.descending)在下面。当升序激活时,.ascending箭头变蓝,.descending隐藏;降序激活时,.descending变蓝,.ascending隐藏。 */ /* 因此,我们修改激活状态的颜色为绿色 */ .el-table .ascending .sort-caret.ascending { border-bottom-color: #67c23a; /* 升序激活时,升序箭头(上箭头)的颜色 */ } .el-table .descending .sort-caret.descending { border-top-color: #67c23a; /* 降序激活时,降序箭头(下箭头)的颜色 */ } /* 但是,激活状态时,表头单元格会添加.ascending.descending类,因此我们可以这样写: */ .el-table th.ascending .sort-caret.ascending { border-bottom-color: #67c23a; } .el-table th.descending .sort-caret.descending { border-top-color: #67c23a; } /* 另外,我们还需要确保在未激活状态时两个箭头都是灰色 */ .el-table th .sort-caret { border-top-color: #c0c4cc; border-bottom-color: #c0c4cc; } /* 注意:在未激活状态下,两个箭头都会显示,所以设置两个边框色都为灰色 */ /* 但是,上面的写法可能会覆盖激活状态,所以我们要确保激活状态的选择器优先级更高 */ /* 更精确的写法:单独设置两个箭头在默认状态下的颜色 */ .el-table th .sort-caret.ascending { border-bottom-color: #c0c4cc; /* 升序箭头(上箭头)的底部边框色 */ } .el-table th .sort-caret.descending { border-top-color: #c0c4cc; /* 降序箭头(下箭头)的顶部边框色 */ } ``` 然而,在Element UI中,箭头是由两个元素(i标签)分别构成的,每个i标签都有类名`sort-caret`和`ascending`(或`descending`)。每个i标签利用边框绘制一个三角形。 因此,我们可以这样覆盖: ```css /* 默认状态(未激活)下,两个箭头都为灰色 */ .el-table .caret-wrapper .sort-caret.ascending { border-bottom-color: #c0c4cc; } .el-table .caret-wrapper .sort-caret.descending { border-top-color: #c0c4cc; } /* 激活状态下,当前排序方向的箭头为绿色 */ .el-table .caret-wrapper .ascending.sort-caret.ascending { border-bottom-color: #67c23a; } .el-table .caret-wrapper .descending.sort-caret.descending { border-top-color: #67c23a; } ``` 但是注意,在激活排序时,表头单元格(th)会添加一个类名(升序为`ascending`,降序为`descending`),同时激活的箭头会有一个内联样式(`opacity:1`),而另一个箭头为`opacity:0.2`(实际上几乎看不见)。但我们这里通过边框颜色覆盖,可以不用考虑透明度。 但是,如果我们只想改变激活箭头的颜色,而不影响另一个箭头(未激活的那个),那么上面的写法是可行的。 另外,我们也可以改变激活状态下列头文字的颜色: ```css /* 激活状态下列头文字颜色 */ .el-table th.ascending, .el-table th.descending { color: #67c23a; /* 绿色 */ } ``` 综合以上,我们给出完整样式覆盖: ```css /* 默认状态(未激活)的排序箭头颜色 */ .el-table .caret-wrapper .sort-caret.ascending { border-bottom-color: #c0c4cc; } .el-table .caret-wrapper .sort-caret.descending { border-top-color: #c0c4cc; } /* 激活状态下的排序箭头颜色 */ .el-table th.ascending .sort-caret.ascending { border-bottom-color: #67c23a; } .el-table th.descending .sort-caret.descending { border-top-color: #67c23a; } /* 激活状态下的列头文字颜色(可选) */ .el-table th.ascending, .el-table th.descending { color: #67c23a; } ``` 注意:如果以上选择器优先级不够,可以适当增加权重(比如重复类名或使用!important),但尽量不使用!important。 使用方式: 在项目的全局样式文件(如index.css)或者当前组件的样式中(如果是scoped,需要使用深度选择器)添加以上样式。 如果是scoped样式,需要这样写: ```vue <style scoped> /* 使用深度选择器 */ ::v-deep .el-table .caret-wrapper .sort-caret.ascending { border-bottom-color: #c0c4cc; } ::v-deep .el-table .caret-wrapper .sort-caret.descending { border-top-color: #c0c4cc; } ::v-deep .el-table th.ascending .sort-caret.ascending { border-bottom-color: #67c23a; } ::v-deep .el-table th.descending .sort-caret.descending { border-top-color: #67c23a; } /* 如果还想改变文字颜色 */ ::v-deep .el-table th.ascending, ::v-deep .el-table th.descending { color: #67c23a; } </style> ``` 注意:在Vue 3中,使用 `:deep()` 代替 `::v-deep`。 这样,就可以实现未点击时排序箭头为灰色,点击激活排序时变为绿色的效果了。 如果希望降序激活时也变成绿色,同理。 另外,如果遇到样式覆盖不生效的问题,请检查样式加载顺序(确保自定义样式在Element UI样式之后)以及选择器优先级。 相关问题: 1. 如何修改Element UI表格排序箭头的形状? 2. 如何在Element UI表格中实现多列排序? 3. 如何禁用Element UI表格某一列的排序功能? </think> 要实现在 Element UI 表格中排序箭头未点击时为灰色、点击激活后变为指定颜色(如绿色)的效果,可通过自定义 CSS 覆盖默认样式实现。以下是具体解决方案: ### 核心 CSS 代码 ```css /* 默认状态 - 灰色箭头 */ .el-table .caret-wrapper .sort-caret { border-top-color: #c0c4cc; /* 上箭头灰色 */ border-bottom-color: #c0c4cc; /* 下箭头灰色 */ } /* 升序激活状态 - 绿色上箭头 */ .el-table .ascending .sort-caret.ascending { border-bottom-color: #67c23a !important; /* 指定绿色 */ } /* 降序激活状态 - 绿色下箭头 */ .el-table .descending .sort-caret.descending { border-top-color: #67c23a !important; /* 指定绿色 */ } /* 激活状态下列头文字颜色 */ .el-table th.ascending, .el-table th.descending { color: #67c23a !important; /* 列头文字变绿色 */ } ``` ### 实现原理说明 1. **默认状态** 通过 `.sort-caret` 选择器设置所有箭头为灰色 `#c0c4cc` - 上箭头:`border-top-color` 控制 - 下箭头:`border-bottom-color` 控制 2. **激活状态** 当列头被点击激活时: - 升序状态(`.ascending`):下箭头变为绿色 `#67c23a` - 降序状态(`.descending`):上箭头变为绿色 ``` .el-table .ascending .sort-caret.ascending { ... } ``` 3. **文字颜色同步** 激活时列头文字同步变为绿色: ```css .el-table th.ascending, .el-table th.descending { color: #67c23a !important; } ``` ### 使用方法 #### 方案1:全局样式(推荐) 在全局 CSS 文件(如 `src/assets/styles.css`)中添加上述代码 #### 方案2:组件内样式(Vue SFC) ```vue <template> <el-table :data="tableData" @sort-change="handleSort"> <el-table-column prop="date" sortable label="日期"></el-table-column> <el-table-column prop="name" sortable label="姓名"></el-table-column> </el-table> </template> <style scoped> /* 深度选择器穿透 */ ::v-deep .el-table .caret-wrapper .sort-caret { border-top-color: #c0c4cc; border-bottom-color: #c0c4cc; } ::v-deep .el-table .ascending .sort-caret.ascending { border-bottom-color: #67c23a; } ::v-deep .el-table .descending .sort-caret.descending { border-top-color: #67c23a; } ::v-deep .el-table th.ascending, ::v-deep .el-table th.descending { color: #67c23a; } </style> ``` ### 效果对比 | 状态 | 上箭头颜色 | 下箭头颜色 | 文字颜色 | |------------|------------|------------|-------------| | 默认未激活 | 灰色 | 灰色 | 默认深灰色 | | 升序激活 | 灰色 | **绿色** | **绿色** | | 降序激活 | **绿色** | 灰色 | **绿色** | > **颜色自定义**:将代码中的 `#67c23a` 替换为任意 HEX/RGB 颜色值即可更改激活颜色[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值