题目传送门: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. 2018.09.15 vijos1053Easy sssp(最短路)

    传送门 貌似可以最短路时同时判定负环啊. 但我不想这样做. 于是写了一个dfs版的判环,bfs版的求最短路. 代码: #include<iostream> #include<ccty ...

  2. redis学习-事务命令

    multi:开启事务 exec:提交事务 discard:取消事务 1.开启事务之后,每次执行命令之后,都要先进入事务队列中,只有在执行 exec之后才开始执行 2.开启事务之后,每次执行命令之后,都 ...

  3. 19. Fight over Fox-hunting 猎狐引发的冲突

    . Fight over Fox-hunting 猎狐引发的冲突 ① Foxes and farmers have never got on well.These small dog-like ani ...

  4. 主机和docker容器拷贝文件

    从主机复制到容器sudo docker cp host_path containerID:container_path 从容器复制到主机sudo docker cp containerID:conta ...

  5. vue实现消息的无缝滚动效果

    export default { data() { return { animate:false, items:[ {name:"马云"}, {name:"雷军" ...

  6. go指针的一个小坑

    几乎可以肯定的说,go语言中除了闭包在引用外部变量的时候是传引用的,其他的时候都是传值的.如果你说形参可以定义为指针.好吧,那么告诉你这个指针的值其实是按照传值的方式使用的. 下面看个很浅显的例子: ...

  7. vim 配置半透明

    转载两个博客 链接一 链接二

  8. 来回最短路POJ3268

    这个题得主要考点在于给你的图是去了再回来得有向图,如何模块化解决呢就是转变图的方向,我们根据初始得放心求出每个点到x得最短路,然后转变所有路得方向再求出所有点到x得最短路,最后一相加就是最后的来回了~ ...

  9. express4.X 笔记

    express是node的web框架,更新频繁,3.X到4.X有了很大的改变.网上的例子,各种版本的都有,为了以后方便,现在重新认真看一遍4.X的API,统一以后的使用方法.在J2EE上落后了,在ex ...

  10. Android 广播代码的发送与接收

    Android四大组件之一广播,使用的也比较多,广播可大致分为两种,一种是Android系统区域的广播,是由系统指令发出,例如:点亮屏幕广播,开机过程中的一些广播 省略-, 然而还有一种广播就是我们自 ...