题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6058

题目大意:给你一个$1$到$n$的排列,请求出该序列所有区间中第$k$大之和,若该区间内少于$k$个数,则不计算答案。

数据范围: $n≤5*10^5,k≤50$。

想出来了好像真的是模拟题(然而我并没完全独立思考)。

和上午做的某一题挺像的。

我们考虑数字$x$,不难发现,我们只要分别找出该数字左边和右边大于它的$k-1$个数字分别是什么,然后简单地扫一遍就可以得出$x$作为第$k$大的数字出现的次数。

下面考虑如何求出数字$x$两侧比它大的数字。

我们将输入的数字从小到大处理,对于数字$x$,我们维护一个双向链表,按照原序列的殊勋保存所有$>x$的数字,每次处理完$x$后,将$x$从该链表中删除。

不难发现,初始时链表中只有$n$个元素,且删除一个元素耗时为$O(1)$,且每次扫描为$O(k)$,故总时间复杂度为$O(n*k+n log n)$。

 #include<bits/stdc++.h>
#define M 500005
#define L long long
using namespace std; int l[M]={},r[M]={},a[M]={},p[M]={};
int n,k; L ans=;
bool cmp(int x,int y){return a[x]<a[y];}
int main(){
int cas=; cin>>cas;
while(cas--){
ans=;
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%d",a+i),p[i]=i;
for(int i=;i<=n;i++) r[i]=i+,l[i]=i-;
sort(p+,p+n+,cmp);
for(int i=;i<=n;i++){
int id=p[i];
int lid,lcnt=;
for(lid=id;l[lid]!=&&lcnt!=k;lid=l[lid],lcnt++);
int rid=id,rcnt=;
while(lcnt+rcnt<k&&r[rid]!=n+){
rid=r[rid];
rcnt++;
}
if(lcnt+rcnt==k){
while(rid!=n+){
L ll=lid-l[lid],rr=r[rid]-rid;
ans+=ll*rr*a[id];
if(lid==id) break;
lid=r[lid]; rid=r[rid];
}
}
lid=l[id]; rid=r[id];
r[lid]=rid; l[rid]=lid;
}
cout<<ans<<endl;
}
}

【hdu6058】 Kanade's sum 模拟的更多相关文章

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

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

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

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

  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. 【set】【链表】hdu6058 Kanade's sum

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

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

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

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

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

随机推荐

  1. Linux shell脚本的字符串截取

    http://blog.csdn.net/gumanren/article/details/5601544 Linux 的字符串截取很有用.有八种方法. 假设有变量 var=http://www.ha ...

  2. Android系统root破解原理分析

    http://dengzhangtao.iteye.com/blog/1543494 root破解过程的终极目标是替换掉系统中的su程序.但是要想替换掉系统中su程序本身就是需要root权限的,怎样在 ...

  3. python之数据类型1

    什么是数据类型及数据类型分类        python中的数据类型 python使用对象模型来存储数据,每一个数据类型都有一个内置的类,每新建一个数据,实际就是在初始化生成一个对象,即所有数据都是对 ...

  4. 2018.10.19 bzoj1584: Cleaning Up 打扫卫生(线性dp)

    传送门 dp妙题. 考虑到每个位置分一组才花费nnn的贡献. 因此某一段不同的数的个数不能超过sqrt(n)sqrt(n)sqrt(n),于是对于当前的位置iii我们记pos[j]pos[j]pos[ ...

  5. 第九章:叹词(L'interjection )

    ➊叹词的使用词类 .拟声词.如:    Ah !啊!呀!哎!      Hein  !嗯!呣!哎!    Paf  !啪!叭!             Pouf  !扑通(重物坠地声)    Euh ...

  6. SPSS-单因素方差分析(ANOVA) 案例解析

    继续以上一期的样本为例,雌性老鼠和雄性老鼠,在注射毒素后,经过一段时间,观察老鼠死亡和存活情况. 研究的问题是:老鼠在注射毒液后,死亡和存活情况,会不会跟性别有关? 样本数据如下所示: (a代表雄性老 ...

  7. x+y+z=n的正整数解

    题:x+y+z=n,其中(n>=3),求x,y,z的正整数解的个数根据图象法:x>=1,y>=1,x+y<=n-1

  8. 201709019工作日记--Java中的各种锁--未解决

    1. Syncronized与ReentrantLock Synchronized比ReentrantLock进java标准早,因此一开始大家都是用它.相当于Java提供了一种封装的互斥锁机制,对于用 ...

  9. node express session

    在express4.0版本以上,需要单独增加session模块:express-session:https://www.npmjs.com/package/express-session 具体做法是, ...

  10. springMVC 开涛 Controller接口控制器

    通过注解实现控制器类,所以不用看Controller接口了.把之前的笔记保存下. 笔记(图片):http://pan.baidu.com/s/1mgMNDna 第三章看不太懂,3.2 3.3.只了解到 ...