2017 Multi-University Training Contest - Team 3—HDU6058 Kanade's sum
题目链接: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的更多相关文章
- 【2017 Multi-University Training Contest - Team 3】Kanade's sum
[Link]:http://acm.hdu.edu.cn/showproblem.php?pid=6058 [Description] 给你n个数; 它们是由(1..n)组成的排列; 然后给你一个数字 ...
- 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) ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- UIWebView和UICollectionViewController的使用
UIWebView和UICollectionViewController的使用 UIWebView UIWebView是iOS内置的浏览器的控件, 可以浏览网页, 打开文档等 .系统自带的Safari ...
- JAVA-Word转PDF各种版本实现方式
当下做一个项目,就是各种操作office,客户的需求总是各种不按常理,来需求就得搞啊.对JAVA操作office这方面真是头大,弟弟是真滴不懂不会啊.无奈只好试啊试的.网上一大堆好使的,一大堆不好使的 ...
- Missing separate debuginfos, use: debuginfo-install
环境:CentOS6.2 64位 操作:使用gdb调试C++查询MySQL数据库的程序 原因: 解决办法: 1. 修改文件/etc/yum.repos.d/CentOS-Debuginfo.repo ...
- 解决在eclipse中配置Tomcat时,出现"Cannot create a server using the selected type"的错误
比如说使用tomcat 这是因为你之前创建过一次,比如说tomcat6,你指定的目录是:D:/tomcat-6.0.3 后来因为某种原因你把tomcat删了,然后你又安装到了E:/tomcat-6.0 ...
- CSS学习笔记(11)--Flex 布局教程:语法篇
原文--阮一峰博客 作者: 阮一峰 日期: 2015年7月10日 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 ...
- lua自用的函数收集
这里记录一下我常用到的一些lua函数,不定期更新. 1.cirleAdd函数是用来一个循环自增的,其中num是最大值, startNum是起始值,stepNum是步长,startFlag默认真起始值从 ...
- strerror和perror函数详解
/*#include <string.h> char *strerror(int errnum); 它返回errnum的值所对应的错误提示信息,例如errnum等于12的话,它就会返回&q ...
- jquery设置radio选中
<script type="text/javascript"> $(document).ready(function(){ $("input[type=rad ...
- 如何使用PHP开发高效的WEB系统
PHP是一个非常优秀的工具,它能够简单,也能够复杂.不一样的项目,应该用不一样的PHP. 小项目 - 简单而直接的PHP 一般对于一个功能页面在20下面的站点.我们能够用一个非常easy的框架结构来 ...
- 让浏览器下载文件http头部
网站提供下载服务时经常需要实现一个强制下载功能(即强制弹出下载对话框),并且文件名保持和用户之前上传时相同. 效果如下图: Content-Disposition 使用 HTTP Header 的 ...