hdu6058
hdu6058
题意
定义 \(f(l, r, k)\) 函数为区间 \([l, r]\) 第 \(k\) 大的数,如果 \(r - l + 1 < k\),\(f = 0\) 。求 \(\sum_{l=1}^{n}\sum_{r=l}^{n}f(l, r, k)\) 。
分析
我们直接去算每个数字在多少个区间为第 \(k\) 大的数,那么一定和它前面和后面的 \(k\) 个大于它的数有关(如果有的话),现在问题就是怎么快速找出它前面和后面大于它的 \(k\) 个数。
对于 \([1, n]\) 每个数,用两个数组分别指向它所在的位置前面的值和后面的值的位置,那么从 \(1\) 到 \(n\) 计算,算完之后删掉(更改它后面的值向前的指向,更改它前面的值向后的指向),这样对于每个数向左向右最多跳 \(k\) 次。复杂度 \(O(k * n)\) 。
code
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN = 5e5 + 10;
int n, k;
int pre[MAXN], nxt[MAXN], pos[MAXN];
int l[MAXN], r[MAXN];
void del(int x) {
pre[nxt[x]] = pre[x];
nxt[pre[x]] = nxt[x];
}
ll cal(int x) {
int c1 = 0, c2 = 0;
for(int i = x; i > 0; i = pre[i]) {
l[++c1] = i - pre[i];
if(c1 == k) break;
}
for(int i = x; i <= n; i = nxt[i]) {
r[++c2] = nxt[i] - i;
if(c2 == k) break;
}
ll res = 0;
for(int i = 1; i <= c1; i++) {
if(k - i + 1 <= c2) {
res += 1LL * l[i] * r[k - i + 1];
}
}
return res;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++) {
int x;
scanf("%d", &x);
pos[x] = i;
pre[i] = i - 1;
nxt[i] = i + 1;
}
pre[0] = 0; nxt[n + 1] = n + 1;
ll ans = 0;
for(int i = 1; i <= n; i++) {
ans += cal(pos[i]) * i;
del(pos[i]);
}
printf("%lld\n", ans);
}
return 0;
}
hdu6058的更多相关文章
- hdu6058[链表维护] 2017多校3
用一个双向链表来查找比当前元素大的前k-1个元素和后k-1个元素 ,从小到大枚举x,算完x的贡献后将x从链表中删除,优化到O(nk). /*hdu6058[链表维护] 2017多效3*/ #inclu ...
- hdu-6058 Kanade's sum
题意:略 思路:要我们求每个区间第K大数之和,其实可以转换为求多少个区间的第K大数是X,然后我们在求和就好了. 那么我们可以从小到大枚举所有可能成为第K大的数.为什么从小到大呢? 因为从小到大我们就略 ...
- 【hdu6058】 Kanade's sum 模拟
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题目大意:给你一个$1$到$n$的排列,请求出该序列所有区间中第$k$大之和,若该区间内少于$ ...
- 2017 Multi-University Training Contest - Team 3—HDU6058 Kanade's sum
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题目意思:给你一个排列,求所有区间长度大于等于k的区间第k大的数的和…… 思路:一开始看到区间k ...
- HDU6058 Kanade's sum(思维 链表)
Kanade's sum Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- 【set】【链表】hdu6058 Kanade's sum
f(l,r,K)表示区间l,r里面的K大值,问你所有连续子区间的f之和. l(i)表示i左侧第一个比它大的数的位置,r(i)表示i右侧第一个比它大的数的位置.可以用set处理出来. 把数从大到小排序, ...
- hdu6058 Kanade's sum 区间第k大
/** 题目:Kanade's sum 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题意:给定[1,n]的排列,定义f(l,r,k)表示区间[l ...
随机推荐
- [CF543D]Road Improvement
题目大意:给定一个无根树,给每条边黑白染色,求出每个点为根时,其他点到根的路径上至多有一条黑边的染色方案数,模$1e9+7$. 题解:树形$DP$不难想到,记$f_u$为以$1$为根时,以$u$为根的 ...
- Laravel中Redis的使用
安装 laravel中使用redis首先需要你通过 Composer 安装 predis/predis 包: composer require predis/predis 配置 redis的配置文件是 ...
- [Leetcode] remove element 删除元素
Given an array and a value, remove all instances of that value in place and return the new length. T ...
- 线程 condition_variable
http://www.cnblogs.com/haippy/p/3252041.html 理解wait():当前线程调用 wait() 后将被阻塞(此时当前线程应该获得了锁(mutex).在线程被阻塞 ...
- 常见编程语言对REPL支持情况小结
最近跟一个朋友聊起编程语言的一些特性,他有个言论让我略有所思:“不能REPL的都是渣”.当然这个观点有点偏激,但我们可以探究一下,我们常用的编程语言里面,哪些支持REPL,哪些不支持,还有REPL的一 ...
- SQL优化单表案例
数据准备: -- 创建数据库 mysql> create database db_index_case; Query OK, row affected (0.00 sec) -- 查看数据库 m ...
- ES6学习笔记(四)—— async 函数
await 是 async wait 的简写, 是 generator 函数的语法糖. async 函数的特点: async 声明一个方法是异步的,await 则等待这个异步方法执行的完成 async ...
- 我们用CloudStack做什么
原文地址:http://www.sdfengxi.com/?p=376 我想很多同学会有类似的疑问,就是我配置好了CloudStack或者OpenStack之类的环境之后能够提供什么服务或者应用呢?下 ...
- Android百度地图的使用
做关于位置或者定位的app的时候免不了使用地图功能,本人最近由于项目的需求需要使用百度地图的一些功能,所以这几天研究了一下,现写一下blog记录一下,欢迎大家评论指正! 一.申请AK(API Key) ...
- 粉刷匠(bzoj 1296)
Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个 ...