首页 > 代码库 > hdu 6058
hdu 6058
http://acm.hdu.edu.cn/showproblem.php?pid=6058
题意:求区间第K大然后乘以它本身的总和
思路:枚举X,维护一个链表,这个链表是记录比它小的一些,比他大的有多少个的一个链表
因为在这个链表中隔K个的值,然后取第K大就一定是X
然后维护这个链表呢,就是指已经枚举过的X就不要出现在这个链表里面了,因为如果它的值比这个X要小的话,肯定是不会影响这个第K大的
然后不可能出现比它大的情况,因为我们枚举X是从小到大枚举的,所以这个问题就可以化解
1 #include <stdio.h> 2 #include <string.h> 3 #define maxn 500005 4 5 struct Node { 6 int pre, next; 7 int val; 8 }node[maxn]; 9 10 int next[maxn]; 11 int pre[maxn]; 12 13 int main() 14 { 15 int t, a; 16 int m, k; 17 scanf("%d", &t); 18 while (t--) 19 { 20 scanf("%d%d", &m, &k); 21 for (int i = 1; i <= m; i++) { 22 scanf("%d", &a); 23 node[i].pre = i - 1; 24 node[i].next = i + 1; 25 node[a].val = i; 26 } 27 long long ans = 0; 28 for (int i = 1; i <= m - k+1; i++) 29 { 30 int pos = node[i].val; 31 int pr = 0; 32 int ne = 0; 33 for (int j = pos; j&&pr <= k + 1; j = node[j].pre) pre[++pr] = j; //找到前面比它小的 34 for (int j = pos; j&&ne <= k + 1; j = node[j].next) next[++ne] = j; //找到后门比它大的 35 pre[++pr] = 0; 36 next[++ne] = m + 1; 37 for (int j = 1; j < pr; j++) 38 { 39 if (k - j + 1 < ne && k - j + 1 >= 1) 40 { 41 ans += (long long)(next[k + 1 - j + 1] - next[k + 1 - j])*(pre[j] - pre[j + 1])*i; //i一定为这个区间的第K大 42 } 43 } 44 node[node[pos].pre].next = node[pos].next; //链表的维护 45 node[node[pos].next].pre = node[pos].pre; 46 node[pos].pre = node[pos].next = 0; 47 } 48 printf("%lld\n", ans); 49 } 50 return 0; 51 }
hdu 6058
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。