题目链接: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. Hp && Dell服务器硬件监控

    HP 安装HP工具: yum install hpssacli 1 查看控制器状态 raid卡型号等hpssacli ctrl all show status 2 查看硬盘类型.大小 raid级别.状 ...

  2. 修改JQM的默认配置属性

    从本文开始,使用 jQuery Mobile 与 HTML5 开发 Web App 系列将会进入第三部分——jQuery Mobile 事件与方法,这其中将会利用之前所讲述的 jQuery Mobil ...

  3. 利用ngModel相关属性及方法自定义表单验证指令

    这是一个只能输入偶数的验证指令

  4. 使用ICSharpCode.TextEditor制作一个语法高亮显示的XML编辑器

    使用ICSharpCode.TextEditor制作一个语法高亮显示的XML编辑器 品高工作流 的流程模拟器中使用了一个具有语法高亮和折叠功能的XML编辑器,其核心就是用了SharpDevelop中的 ...

  5. python学习笔记(11)--爬虫下载漫画图片

    说明: 1. 某本子网站爬虫,现在只实现了扒取一页,已经凌晨两点了,又饿又困,先睡觉,明天再写总结吧! 2. 我是明天,我来写总结了! 3. 这个网站的结构是这样的: 主页: 主页-第1页-漫画1封面 ...

  6. love2d--glsl02变量和语句

    Shader分为顶点着色器和片段着色器,GPU先处理顶点再处理片段,大概可以这么理解, 顶点着色器处理模型里的点,输出处理后的数据,这些数据经过GPU其它模块处理后传入 片段着色器,经片段着色器综合后 ...

  7. 一些lua代码

    1.把k--v表转化为数组表,只支持2级 2.取中值 3.字符串按每行最多n像素分割,并返回每行最大宽度,可以用"\n"手动换行

  8. 0810 smarty

    1.Smarty简介(why,what) why:smarrty 将前端工程师和程序员的工作分开,让前端工程师完成前台页面的工作,程序员完成后台的业务逻辑.what模版引擎是用来将PHP代码和模版页组 ...

  9. koa介绍

    https://github.com/koajs/koa https://github.com/demopark/koa-docs-Zh-CN ctx.response.type = 'json'; ...

  10. qt 使用多个ui文件

    一般的QT工程只有一个ui,本文记录如何在一个工程中使用多个ui文件. 参考链接: http://www.cnblogs.com/lc-cnblong/p/3182903.html 创建方法,鼠标在工 ...