题目传送门: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. Pseudo-class和pseudo-element的差别

    相同点: Pseudo-class和pseudo-element的语法都是以selector或者selector.class开始的. 不同点: Pseudo-class的操作对象是文档树中已有的元素, ...

  2. c++编程思想里面的错误(可能c++标准变了,所以以前的东西没有更新)

    第一卷  第五章 5.3友元 下面的代码是<c++编程思想>里面的代码, struct X; struct Y{ void f(X*); }; struct X{ private: int ...

  3. I2C笔记

      SCL:上升沿将数据输入到每个EEPROM器件中:下降沿驱动EEPROM器件输出数据.(边沿触发) SDA:双向数据线,为OD门,与其它任意数量的OD与OC门成"线与"关系. ...

  4. iphone“连接到icloud是出错”的可能原因

    百度没能解决"连接到icloud是出错",突然发现是因为禁止了"设置"访问WIFI和蜂窝网络(第三张图所示). ​

  5. 11.字符串{a,b}的幂集[回溯递归]

    我一直在想着这个事,早晨起来五六点,躺在床上冥想.突然悟解了,真如某些书上写的,大道不过三言两语,说破一文不值.还是按照老方法,把问题最大程度的精简,现在求集合A={a,b}的幂集,只有两个元素,应该 ...

  6. springmvc elf8848

    刚开始觉得孔浩讲得好,之后觉得开涛讲得好,现在觉得elf8848讲得好.其实只是自己学习的各个阶段 孔浩:环境搭建,做了个基础的CRUD 开涛:讲了Controller(不该看),注解,数据绑定,请求 ...

  7. Delphi XE5 图解为Android应用制作签名

    http://redboy136.blog.163.com/blog/static/107188432201381872820132 Delphi XE5 图解为Android应用制作签名 2013- ...

  8. N个不同球取出M个的组合个数求解

    Technorati 标签: 组合,概率 从N个不同的球中取出M个,一共有多少种取法? 这个问题是组合数据的基本问题,考虑拿出球是否放回,拿出去的球是否有序,它有4种变体: 不放回,有序: 不放回,无 ...

  9. Flash(as3) 调整显示对象颜色

    在游戏开发中改变显示对象的颜色是比较常见的操作,那么除了在FlashCS中调整,AS3又提供了怎样的方式呢? ColorTransform 这个类是轻量级的应用,其构造参数如下: ColorTrans ...

  10. AbpZero之企业微信---登录(拓展第三方auth授权登录)---第二步:开始逐步实现企业微信登录

    上回分解到AbpZero的auth登录机制,这里我们开始着手逐步实现我们的auth登录. 我们新建一个类库XXXX.Web.Authentication.External 在类库下新建一个类QYWec ...