Kanade's sum

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 871    Accepted Submission(s): 357

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
 
Source

【题意】给你一个序列,(1~n的一个全排列),然后询问所有的子区间第k大的数,累加起来,如果区间长度不足k,则为0,求累加     和。

【分析】由于区间数量太多,我们考虑算每个数的贡献。一个数的贡献显然就是它所能存在的区间数量,在这些区间内它是第k大。首先,要保证它是这个区间里的第k大,那么我们必须在他左边和右边找到共k-1个比他大的,然后围成区间就行。我们可以再这个数左边找到最多k个比他大的,右边找到最多k个比他大的(如果存在k个的话)。比如x是当前枚举的数,k=3,a,b,c是左边比他大的数的位置,d,e,f是右边比他大的数的位置(都是位置离x最近的),现在就是这样a  b  c  x  d  e  f,那么现在x的贡献就是能够围成的所有合法区间的数量,比如我们可以左边取x,右边取d e,那么此时的贡献就是(x-c)*(f-e),也可以左边取c,x,右边取d,此时的贡献就是(c-b)*(e-d)...

这样我们把贡献累加起来就是了,但是现在的问题是如何找这k个数。

我们发现当我们枚举到x时,找k个数是直接跨过了比x小的数,直接跳到了比x大的,所以我们可以从小到大枚举x,用一个链表把所有比x大的数连起来,当我们处理完x的时候,我们就把x的位置从链表里删除,这样我们的链表里存的都是比x大的数,而且相对位置也没变。这样我们就是O(k)找到这k个数.总时间复杂度,O(n*k)。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long ll;
const int N = 5e5+;;
const int M = ;
const int mod = 1e9+;
const double pi= acos(-1.0);
typedef pair<int,int>pii;
int n,k;
int pos[N],pre[N],suf[N];
int l[N],r[N];
void del(int x){
int pree=pre[x];
int suff=suf[x];
if(pree)suf[pree]=suff;
if(suff<=n)pre[suff]=pree;
pre[x]=suf[x]=;
}
int main() {
int T;
scanf("%d",&T);
while(T--){
ll ans=;
scanf("%d%d",&n,&k);
for(int i=,x;i<=n;i++){
scanf("%d",&x);
pos[x]=i;
}
for(int i=;i<=n;i++){
pre[i]=i-;
suf[i]=i+;
}
for(int x=;x<=n-k+;x++){
l[]=r[]=;
int p=pos[x];
for(int i=p;i&&l[]<=k+;i=pre[i])l[++l[]]=i;
for(int i=p;i<n+&&r[]<=k+;i=suf[i])r[++r[]]=i;
l[++l[]]=;
r[++r[]]=n+;
for(int i=;i<l[];i++){
if(i+r[]>=k+&&i<=k){
ans+=1LL*(l[i]-l[i+])*1LL*(r[k-i+]-r[k-i+])*x;
}
}
del(p);
}
printf("%lld\n",ans);
}
return ;
}

HDU6058 Kanade's sum(思维 链表)的更多相关文章

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

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

  2. 【set】【链表】hdu6058 Kanade's sum

    f(l,r,K)表示区间l,r里面的K大值,问你所有连续子区间的f之和. l(i)表示i左侧第一个比它大的数的位置,r(i)表示i右侧第一个比它大的数的位置.可以用set处理出来. 把数从大到小排序, ...

  3. hdu-6058 Kanade's sum

    题意:略 思路:要我们求每个区间第K大数之和,其实可以转换为求多少个区间的第K大数是X,然后我们在求和就好了. 那么我们可以从小到大枚举所有可能成为第K大的数.为什么从小到大呢? 因为从小到大我们就略 ...

  4. 2017 Multi-University Training Contest - Team 3—HDU6058 Kanade's sum

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题目意思:给你一个排列,求所有区间长度大于等于k的区间第k大的数的和…… 思路:一开始看到区间k ...

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

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

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

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

  7. HDU 6058 Kanade's sum 二分,链表

    Kanade's sum Problem Description Give you an array A[1..n]of length n. Let f(l,r,k) be the k-th larg ...

  8. 2017 Multi-University Training Contest - Team 3 Kanade's sum hd6058

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6058 题目: Kanade's sum Time Limit: 4000/2000 MS (J ...

  9. 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 ...

随机推荐

  1. vijos 1426 背包+hash

    背景 北京奥运会开幕了,这是中国人的骄傲和自豪,中国健儿在运动场上已经创造了一个又一个辉煌,super pig也不例外……………… 描述 虽然兴奋剂是奥运会及其他重要比赛的禁药,是禁止服用的.但是运动 ...

  2. POJ 2891- Strange Way to Express Integers CRT 除数非互质

    题意:给你余数和除数求x 注意除数不一定互质 思路:不互质的CRT需要的是将两个余数方程合并,需要用到扩展GCD的性质 合并互质求余方程 m1x -+ m2y = r2 - r1 先用exgcd求出特 ...

  3. 【C++对象模型】第五章 构造、解构、拷贝 语意学

    1.构造语义学 C++的构造函数可能内带大量的隐藏码,因为编译器会扩充每一个构造函数,扩充程度视 class 的继承体系而定.一般而言编译器所做的扩充操作大约如下: 所有虚基类成员构造函数必须被调用, ...

  4. PowerDesigner16 修改表或表的字段Name的时候不让Code不自动跟着变

    在修改表或表的字段Name的时候不让Code不自动跟着变,设置如下: tools-> General   Options-> Dialog 去掉勾选 Name To Code mirror ...

  5. MyBatis框架的使用及源码分析(十二) ParameterHandler

    在StatementHandler使用prepare()方法后,接下来就是使用ParameterHandler来设置参数,让我们看看它的定义: package org.apache.ibatis.ex ...

  6. 【BZOJ】1385 [Baltic2000]Division expression

    [算法]欧几里德算法 [题解]紫书原题 #include<cstdio> #include<algorithm> using namespace std; ; int T,t, ...

  7. bzoj 2669 状压DP

    因为最多有8个'X',所以我们可以用w[i][s]来表示现在我们填了前i个数,填的X的为S,因为每次新加进来的数都不影响前面的最小值,所以我们可以随便添加,这样就有了剩下所有位置的方案,每次都这样转移 ...

  8. 关于ssh三大框架整合的碎碎念

    三大框架整合,无非就是一个导jar包,修改配置文件的过程.完了就没事了. 还是有很多细节性的问题 比如在spring中写applicationContext.xml文件时不提示: 解决方法如下: 如果 ...

  9. spring boot 注解说明

    Starters 可以创建自己的Starter,但名字格式不能是 spring-boot-starter-*,而是 *-spring-boot-starter.类似Maven插件的规则.   自动配置 ...

  10. TensorFlow中get_variable共享变量调用

    import tensorflow as tf with tf.variable_scope('v_scope',reuse=True) as scope1: Weights1 = tf.get_va ...