题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058

题目意思:给你一个排列,求所有区间长度大于等于k的区间第k大的数的和……

思路:一开始看到区间k大?结果是所有区间,没那么简单,队友拿一个划分树的模板直接TLE,最后也没有做出来。思路是算出每个点在多少个区间内是第k大的,转换一下问题,找一个区间有k-1个比这个数大的,剩下的数都比他小,这样区间的个数乘以这个数就是这个数的贡献,所以关键在于找那些比这个数大的数都在哪些位置上关键,最好还是从小到大的,前面的思路比赛的时候想到了,就是后面这个优化没想出来,看了题解发现是用链表,感觉真的很6,算是学到了。

具体做法我们建立一个链表这个链表每个点有三个参数pos,pre,nxt,由于我用的是结构体数组建的链表,所以每个点的下标代表他是整个排列中第几小的元素,pos代表他在排列中的位置,pre代表每个点的前续元素的pos,nxt代表他后续元素的pos,刚开始的时候肯定要初始化一下。然后我们先从整个排列中值最小的点开始枚举,这样链表内所有的点都比他大,然后再删除他,这样每次枚举一个点的时候链表中所有其他的点都会比它大,然后每次先往后找k个,再往前找k个。然后卡一个k+1个点的区间。左右区间差乘在一起,最后每个点的贡献加在一起,然后画一个图确定一下边界问题,xjb写一下代码就好了。

代码:

 //Author: xiaowuga
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <queue>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <map>
#include <bitset>
#include <cctype>
#define maxx INT_MAX
#define minn INT_MIN
#define inf 0x3f3f3f3f
#define mem(s,ch) memset(s,ch,sizeof(s))
#define nc cout<<"nc"<<endl
const long long N=*+;
using namespace std;
typedef long long LL;
const int MAXBUF = ;
char buf[MAXBUF], *ps = buf, *pe = buf+;
inline void rnext()
{
if(++ps == pe)
pe = (ps = buf)+fread(buf,sizeof(char),sizeof(buf)/sizeof(char),stdin);
} template <class T>
inline bool readin(T &ans)
{
ans = ;
T f = ;
if(ps == pe) return false;//EOF
do{
rnext();
if('-' == *ps) f = -;
}while(!isdigit(*ps) && ps != pe);
if(ps == pe) return false;//EOF
do
{
ans = (ans<<)+(ans<<)+*ps-;
rnext();
}while(isdigit(*ps) && ps != pe);
ans *= f;
return true;
}
struct node{
int pos,pre,nxt;
}p[N];
int n,k;
LL ans=;
void read(){
for(int i=;i<=n;i++){
int x; readin(x);
p[x].pos=i;
p[i].pre=i-;
p[i].nxt=i+;
}
//把两个边界插进去
p[].pre=;
p[n+].nxt=n+;
}
void solve(){
int lc,rc,rq[];
LL tans;
for(int i=;i<=n;i++){
lc=rc=tans=;
int t=p[i].pos;
for(int j=t;j<=n&&rc<k;j=p[j].nxt){//该节点往前找k个比整个排列第i大的数大的数
rq[++rc]=p[j].nxt-j;
}
for(int j=t;j>&&lc<k;j=p[j].pre){//该节点往后找k个比整个排列第i大的数大的数
lc++;
if(k-lc+>rc) continue;//左右找到的数量大于k的时候,开始计算区间
tans+=(j-p[j].pre)*rq[k-lc+];//此时找到的区间和第一个找到的右区间匹配
}
ans+=tans*i;//计算该点贡献
//删除节点
p[p[t].pre].nxt=p[t].nxt;
p[p[t].nxt].pre=p[t].pre;
}
cout<<ans<<endl;
}
int main() {
int T;
readin(T);
while(T--){
readin(n);readin(k);
k=min(k,);
read();
ans=;
solve();
}
return ;
}

总结:通过从小到大枚举1-n,枚举完一个节点在链表中把他删除,每次枚举的时候这个点都是链表中最小的元素,放心往前往后找k个都是比他大的,感觉这个姿势好厉害。

认识到的不足:可能在确定边界上总是懵逼,以后决定使用画图举例的方式确定边界,然后这个链表的姿势确定是不会,未来可能还得多复习复习这个题。

2017 Multi-University Training Contest - Team 3—HDU6058 Kanade's sum的更多相关文章

  1. 【2017 Multi-University Training Contest - Team 3】Kanade's sum

    [Link]:http://acm.hdu.edu.cn/showproblem.php?pid=6058 [Description] 给你n个数; 它们是由(1..n)组成的排列; 然后给你一个数字 ...

  2. 2017 Multi-University Training Contest - Team 9 1005&&HDU 6165 FFF at Valentine【强联通缩点+拓扑排序】

    FFF at Valentine Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  3. 2017 Multi-University Training Contest - Team 9 1004&&HDU 6164 Dying Light【数学+模拟】

    Dying Light Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  4. 2017 Multi-University Training Contest - Team 9 1003&&HDU 6163 CSGO【计算几何】

    CSGO Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  5. 2017 Multi-University Training Contest - Team 9 1002&&HDU 6162 Ch’s gift【树链部分+线段树】

    Ch’s gift Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  6. 2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】

    Big binary tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  7. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  8. 2017 Multi-University Training Contest - Team 1 1006&&HDU 6038 Function【DFS+数论】

    Function Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  9. 2017 Multi-University Training Contest - Team 1 1002&&HDU 6034 Balala Power!【字符串,贪心+排序】

    Balala Power! Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

随机推荐

  1. [svc]linux buffer和cache的区别

    通俗理解buffer,cache Cache:缓存区,是高速缓存,是位于CPU和主内存之间的容量较小但速度很快的存储器,因为CPU的速度远远高于主内存的速度,CPU从内存中读取数据需等待很长的时间,而 ...

  2. PHP 生成唯一的激活码

    <? php /** * 生成永远唯一的激活码 * @return string */ function create_guid($namespace = null) { static $gui ...

  3. Angular+Electron+VSCode的桌面应用

    Angular+Electron+VSCode的桌面应用 转自:http://blog.csdn.net/yr7942793/article/details/50986696 第一部分 Electro ...

  4. table中添加下拉框

    { file: 'usename', title: '下发用户', width:"20%", align: 'center', templet: function (d) { va ...

  5. Unix系统编程()信号处理器简介

    信号处理器简介 信号处理器程序(也称为信号捕捉器)是当指定信号传递给进程时将会调用的一个函数.这里会学习信号处理器的基本原理,后面将继续学习. 调用信号处理器程序,可能会随时打断主程序流程:内核代表进 ...

  6. 在linux跑xenomai vkworks skin的测试

    1 代码 ############################################################## /* * Copyright (C) 2001,2002,200 ...

  7. wifi设置

    1 编辑/etc/init.d/wifi #!/bin/sh case "$1" in start)     echo /sbin/mdev > /proc/sys/kern ...

  8. [android] AndroidManifest.xml - 【 manifest -> permission】

    在  API Level 1 时被引入 语法: <permission android:description="string resource" android:icon= ...

  9. Ubuntu16.04+cuda8.0+cuDNNV5.1 + Tensorflow+ GT 840M安装小结

    最近重装系统,安装了tensorflow的配置环境 总结一下. 参考资料 http://blog.csdn.net/ZWX2445205419/article/details/69429518 htt ...

  10. HashMap与HashCode有关,用Sort对象排序

    遍历Map,使用keySet()可以返回set值,用keySet()得到key值,使用迭代器遍历,然后使用put()得到value值. 上面这个算法的关键语句: Set s=m.keySet(); I ...