HDU 6058 Kanade's sum 逆序求第k大
来源:互联网 发布:什么是算法的复杂性 编辑:程序博客网 时间:2024/06/01 13:39
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6058
题意:给你一个1-n的排列 求所有自子区间的第K大的和
思路:从大到小插入位置 维护当前数位置 以及当前数前面比他大的个数及位置 后面比他大的及位置 所以k=min(n,80) 链表维护 在保证区间有k-1个比当前大的情况 计算贡献 手写链表维护位置
code:
#include<bits/stdc++.h>using namespace std;typedef long long LL;inline void read(int &x){ x = 0; char p = getchar(); while(!(p <= '9' && p >= '0'))p = getchar(); while(p <= '9' && p >= '0')x *= 10, x += p - 48, p = getchar();}const int MAXN = 5e5 + 10;struct node{ int fro, bac;} pos[MAXN];int a[MAXN], p[MAXN], afro[90], abac[90];int main(){ int t; read(t); for(int cas = 1; cas <= t; cas++) { int n, k;read(n), read(k); for(int i = 0; i <= n + 1; i++) pos[i].fro = 0, pos[i].bac = n + 1; set<int>s;s.insert(0), s.insert(n + 1); set<int>::iterator ite; for(int i = 1; i <= n; i++) { read(a[i]); p[a[i]] = i; } LL ans = 0; for(int i = n; i >= 1; i--) { ite = s.lower_bound(p[i]); int fro = *(--ite), bac = *(++ite); s.insert(p[i]); pos[fro].bac = p[i], pos[p[i]].fro = fro; pos[p[i]].bac = bac , pos[bac].fro = p[i]; fro = bac = p[i]; if(i > n - k + 1) continue; ///计算前k-1 后k-1位置 int fron = 0, bacn = 0; for(int j = 1; j <= k ; j++) { afro[j] = pos[fro].fro; fro = pos[fro].fro; if(fro == 0 || fron == k - 1) break; fron++; } for(int j = 1; j <= k; j++) { abac[j] = pos[bac].bac; bac = pos[bac].bac; if(bac == n + 1 || bacn == k - 1) break; bacn++; } afro[0] = p[i], abac[0] = p[i]; ///计算i对答案的贡献 for(int j = fron; j >= 0; j--) { if(k - j - 1 > bacn) break; LL x1=afro[j] - afro[j + 1],x2=abac[k - j ] - abac[k - j -1],x3=i; ans += x1*x2*x3; } } printf("%lld\n", ans); } return 0;}
阅读全文
0 0
- HDU 6058 Kanade's sum 逆序求第k大
- HDU 6058 Kanade's sum (区间第k大的数的贡献)
- hdu 6058 Kanade's sum [区间第k大数求和] [2017 Multi-University Training Contest
- 2017杭电多校联赛第三场-Kanade's sum (hdu6058) 求第k大的数的和
- HDU-6058 Kanade's sum
- hdu 6058 Kanade's sum
- hdu 6058 Kanade's sum
- hdu 6058 Kanade's sum
- hdu 6058 Kanade's sum
- hdu 6058 Kanade's sum
- [HDU]6058 Kanade's sum
- hdu 6058 Kanade's sum
- hdu--6058Kanade's sum
- Kanade's sum HDU 6058
- HDU 6058 Kanade's sum
- Kanade's sum(hdu 6058)
- HDU 6058 Kanade's sum
- HDU 6058 Kanade's sum
- lintcode--乘积最大子序列
- JS限制input输入的为数字并且有小数的时候最多保留两位小数
- win7删除桌面右键菜单项
- 例题:二维数组打印六阶杨辉三角
- JNI中参数的传递与操作(下)
- HDU 6058 Kanade's sum 逆序求第k大
- I/O多路转接之select服务器
- JQuery点击锚点滚动到相应的模块
- DES 加密解密
- 多核cpu通信的相关寄存器
- 安装raw文件下的apk文件
- HandBrake 开源视频转码器、编码转换器、格式转换器
- redis 安装启动及设置密码<windows>
- openstack虚拟机迁移操作