Kanade's sum

Problem Description
Give you an array A[1..n]of length n.

Let f(l,r,k) be the k-th largest element of A[l..r].

Specially , f(l,r,k)=0 if r−l+1<k.

Give you k , you need to calculate ∑nl=1∑nr=lf(l,r,k)

There are T test cases.

1≤T≤10

k≤min(n,80)

A[1..n] is a permutation of [1..n]

∑n≤5∗105

 
Input
There is only one integer T on first line.

For each test case,there are only two integers n,k on first line,and the second line consists of n integers which means the array A[1..n]

 
Output
For each test case,output an integer, which means the answer.
 
Sample Input
1

5 2

1 2 3 4 5

 
Sample Output
30
 

题解:

  我们只要求出对于一个数x左边最近的k个比他大的和右边最近k个比他大的,扫一下就可以知道有几个区间的k大值是x.

  我们考虑从大到小插入空位,每次维护一个链表,链表里只有>=x的数,那么往左往右找只要暴力跳k次,删除也是O(1)的。

  时间复杂度:O(nk)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #pragma comment(linker, "/STACK:102400000,102400000")
  4. #define ls i<<1
  5. #define rs ls | 1
  6. #define mid ((ll+rr)>>1)
  7. #define pii pair<int,int>
  8. #define MP make_pair
  9. typedef long long LL;
  10. typedef unsigned long long ULL;
  11. const long long INF = 1e18+1LL;
  12. const double pi = acos(-1.0);
  13. const int N = 1e6+, M = 1e3+,inf = 2e9,mod = 1e9 + ;
  14. inline LL read()
  15. {
  16. LL x=,f=;char ch=getchar();
  17. while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
  18. while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
  19. return x*f;
  20. }
  21.  
  22. int n,k,a[N],pos[N],lef[N],righ[N],L[N],R[N];
  23. set<int > G;
  24. set<int >:: iterator it,itt;
  25. void insers(int x,int y) {
  26. int tmp = L[x];
  27. L[y] = tmp;
  28. R[y] = x;
  29.  
  30. R[tmp] = y;
  31. L[x] = y;
  32. }
  33. int main() {
  34. int T;
  35. T = read();
  36. while(T--) {
  37. G.clear();
  38. n = read();
  39. k = read();
  40. for(int i = ; i <= n; ++i) {
  41. a[i] = read();
  42. pos[a[i]] = i;
  43. }
  44. if(k == ) {
  45. puts("");
  46. continue;
  47. }
  48. G.insert();
  49. G.insert(n+);
  50. L[] = -;
  51. R[] = n+;
  52. L[n+] = ;
  53. R[n+] = -;
  54. for(int i = n; i > n - k + ; --i) {
  55.  
  56. it = (G.lower_bound(pos[i]));
  57. insers(*it,pos[i]);
  58. G.insert(pos[i]);
  59. }
  60.  
  61. LL ans = ;
  62. for(int i = n-k+; i >= ; --i) {
  63.  
  64. it = (G.lower_bound(pos[i]));
  65. int po = *it;
  66. for(int j = ; j <= k; ++j) lef[j] = -;
  67.  
  68. lef[] = pos[i];
  69. for(int j = ,h = L[po]; j <= k && h != -; ++j, h = L[h]) {
  70. lef[j] = h;
  71. }
  72. po = *it;
  73. righ[] = pos[i];
  74. for(int j = ,h = po; j <= k && h != -; ++j, h = R[h]) {
  75. righ[j] = h;
  76. if(lef[k-j+] != -)
  77. ans += 1LL*i*(lef[k-j] - lef[k - j + ]) * (righ[j] - righ[j-]);
  78. }
  79. insers(*it,pos[i]);
  80. G.insert(pos[i]);
  81. }
  82. printf("%lld\n",ans);
  83. }
  84. return ;
  85. }

HDU 6058 Kanade's sum 二分,链表的更多相关文章

  1. HDU 6058 - Kanade's sum | 2017 Multi-University Training Contest 3

    /* HDU 6058 - Kanade's sum [ 思维,链表 ] | 2017 Multi-University Training Contest 3 题意: 给出排列 a[N],求所有区间的 ...

  2. hdu 6058 Kanade's sum(模拟链表)

    Kanade's sum Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  3. HDU 6058 Kanade's sum —— 2017 Multi-University Training 3

    Kanade's sum Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  4. 【链表】2017多校训练三 HDU 6058 Kanade's sum

    acm.hdu.edu.cn/showproblem.php?pid=6058 [题意] 给定一个排列,计算 [思路] 计算排列A中每个数的贡献,即对于每个ai,计算有ni个区间满足ai是区间中的第k ...

  5. HDU - 6058 Kanade's sum

    Bryce1010模板 http://acm.hdu.edu.cn/showproblem.php?pid=6058 /* 思路是:找出每个x为第k大的区间个数有多少 用pos[i]保存当前x的位置, ...

  6. 2017ACM暑期多校联合训练 - Team 3 1003 HDU 6058 Kanade's sum (模拟)

    题目链接 Problem Description Give you an array A[1..n]of length n. Let f(l,r,k) be the k-th largest elem ...

  7. hdu 6058 Kanade's sum (计算贡献,思维)

    题意: 给你一个全排列,要你求这个序列的所有区间的第k大的和 思路:比赛的时候一看就知道肯定是算贡献,也知道是枚举每个数,然后看他在多少个区间是第K大,然后计算他的贡献就可以了,但是没有找到如何在o( ...

  8. HDU6058 Kanade's sum(思维 链表)

    Kanade's sum Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  9. hdu6058 Kanade's sum 区间第k大

    /** 题目:Kanade's sum 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题意:给定[1,n]的排列,定义f(l,r,k)表示区间[l ...

随机推荐

  1. POJ 1056 IMMEDIATE DECODABILITY

    IMMEDIATE DECODABILITY Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9630   Accepted: ...

  2. BZOJ 3028 食物 ——生成函数

    把所有东西的生成函数搞出来. 发现结果是x*(1-x)^(-4) 然后把(1-x)^(-4)求逆,得到(1+x+x^2+...)^4 然后考虑次数为n的项前的系数,就相当于选任意四个非负整数构成n的方 ...

  3. [TJOI2009]开关 (线段树)

    题目描述 现有N(2 ≤ N ≤ 100000)盏灯排成一排,从左到右依次编号为:1,2,......,N.然后依次执行M(1 ≤ M ≤ 100000)项操作,操作分为两种:第一种操作指定一个区间[ ...

  4. 转:sudo 的常见用法和参数选项

    原文链接:http://wiki.ubuntu.org.cn/Sudo sudo,以其他用户身份执行一个命令. 用法 sudo -h | -K | -V sudo -v [-Akns] [-g gro ...

  5. phoenixframework集成了所有自动化测试的思想的平台。mark一下。

    phoenixframework http://www.cewan.la/

  6. 作业调度方案(codevs 1156)

    题目描述 Description 我们现在要利用m台机器加工n个工件,每个工件都有m道工序,每道工序都在不同的指定的机器上完成.每个工件的每道工序都有指定的加工时间. 每个工件的每个工序称为一个操作, ...

  7. iOS APP 架构漫谈[转]

      Mark  一下 很不错的文章   最近看了一些有关server的东西,一些很简单的东西,不外乎是一些文档规范,另外结合最近看的wwdc的一些video,觉得对软件架构(software arch ...

  8. array的用法(关于动态选择值)

  9. GridView动态删除Item

    activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...

  10. java使用jxl,自动导出数据excle,quartz自动发送邮件

    =============JAVA后台代码===================== package com.qgc.service.autoSendMsg.AutoSendMsg import ja ...