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. 【BZOJ】1709: [Usaco2007 Oct]Super Paintball超级弹珠

    [算法]模拟 [题解]O(n^2)预处理横线(y),纵线(x),主对角线(y-x+n),副对角线(x+y). 然后n^2枚举每个点.

  2. Problem B. Harvest of Apples(杭电2018年多校+组合数+逆元+莫队)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6333 题目: 题意:求C(n,0)+C(n,1)+……+C(n,m)的值. 思路:由于t和n数值范围太 ...

  3. react-native中使用Echarts,自己使用WebView封装Echarts经验

    1.工作中遇到的问题 我们在使用react-native肯定遇到过各种奇葩的问题,比如引入Echarts时候莫名报错,但是Echarts官网明显告诉我们可以懒加载的,这是因为基本上js大部分原生的组件 ...

  4. base--AuditResult

    //参考base-4.0.2.jar public class AuditResult implements TimeReferable, Serializable //参考api-1.0.0.jar ...

  5. linux 设备树【转】

    转自:http://blog.csdn.net/chenqianleo/article/details/77779439 [-] linux 设备树 为什么要使用设备树Device Tree 设备树的 ...

  6. ThinkPHP5 模型 - 事务支持

    使用事务之前,先确保数据库的存储引擎支持事务操作. MyISAM:不支持事务,主要用于读数据提高性能 InnoDB:支持事务.行级锁和并发 Berkeley DB:支持事务 ThinkPHP5 使用事 ...

  7. Windows 10又现新Bug,24核心竟卡成蜗牛

    Windows 10又现新Bug,24核心竟卡成蜗牛 https://news.cnblogs.com/n/573996/

  8. PXC 避免加入集群时发生SST

    环境 现有集群节点: 192.168.99.210:3101 新加入节点: 192.168.99.211:3101 通过xtrabackup备份还原实例,并通过同步方式追数据: 已有节点情况: roo ...

  9. 项目评审ppt的纲要

    1.prd不能模糊,产品的问题全部明确 2.收益在哪里 3.设计体现业务4.怎样保证数据的前后协作5.异常如何处理6.技术解决的痛点7.对外部依赖8.性能指标预期(响应时间)9.

  10. mui框架 页面无法滚动解决方法

    只需要初始化一下就可以了 mui.init(); 加下面这段代码即可: (function($){ $(".mui-scroll-wrapper").scroll({ //boun ...