hdu 6058 思维
题目:http://acm.hdu.edu.cn/showproblem.php?pid=6058
分析题目的时候,由于枚举的区间很多,而第k大的值范围小,应该要想到去枚举第k大的值然后找到这个值对答案的贡献。
题解:我们只要求出对于一个数x左边最近的k个比他大的和右边最近k个比他大的,扫一下就可以知道有几个区间的kk大值是xx.(这个地方自己举几个例子就知道了)
我们考虑从小到大枚举x,每次维护一个链表(我写了一个双链表),链表里只有大于x的数,每次求x对答案的贡献的时候,直接在链表中x的位置左右k个值扫一边就可以了。
ac代码:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
struct node
{
ll key;
ll l,r;
}num[];
ll a[];
ll pos[];
ll pre[],nex[]; int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
scanf("%d %d",&n,&k);
num[].l=-;
num[n].r=-;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
if(i!=) num[i].l=i-;
if(i!=n) num[i].r=i+;
num[i].key=a[i];
pos[a[i]]=i;
}
ll sum=;
for(int i=;i<=n;i++)
{
fill(pre+,pre+k+,-);
fill(nex+,nex+k+,-);
ll po=pos[i];
ll temp=num[po].l;
int ret=;
pre[]=nex[]=po;
while(temp!=- && ret<=k)
{
pre[ret++]=temp;
temp=num[temp].l;
}
temp=num[po].r;
ret=;
while(temp!=- && ret<=k)
{
nex[ret++]=temp;
temp=num[temp].r;
}
/*
for(int i=1;i<=k;i++) cout<<pre[i]<<' ';
cout<<endl;
for(int i=1;i<=k;i++) cout<<nex[i]<<' ';
cout<<endl;
*/
for(int j=;j<k;j++)
{
if(pre[k-j-]==- || nex[j]==-) continue;
ll ans=pre[k-j-]-pre[k-j];
ll ans2=nex[j+]-nex[j];
if(pre[k-j]==-) ans=pre[k-j-];
if(nex[j+]==-) ans2=n-nex[j]+;
// cout<<ans<<' '<<ans2<<endl;
sum+=ans*ans2*(ll)i;
}
// delete
ll nl=num[po].l;
ll nr=num[po].r;
num[nl].r=nr;
num[nr].l=nl;
}
printf("%lld\n",sum);
}
return ;
}
用链表去维护左右比x大的数还是很神奇的(从小到大去计算贡献值,每次算完小的值就从链表里面删去,,,, 厉害了)。。这个真心没想到
hdu 6058 思维的更多相关文章
- HDU 6058 - Kanade's sum | 2017 Multi-University Training Contest 3
/* HDU 6058 - Kanade's sum [ 思维,链表 ] | 2017 Multi-University Training Contest 3 题意: 给出排列 a[N],求所有区间的 ...
- HDU 2588 思维 容斥
求满足$1<=X<=N ,(X,N)>=M$的个数,其中$N, M (2<=N<=1000000000, 1<=M<=N)$. 首先,假定$(x, n)=m$ ...
- HDU 1431 思维 基础数论
找范围内回文素数,最大到1e8,我就是要枚举回文串,再判素数,然后因为这种弱智思路死磕了很久题目. /** @Date : 2017-09-08 15:24:43 * @FileName: HDU 1 ...
- hdu 6058 Kanade's sum (计算贡献,思维)
题意: 给你一个全排列,要你求这个序列的所有区间的第k大的和 思路:比赛的时候一看就知道肯定是算贡献,也知道是枚举每个数,然后看他在多少个区间是第K大,然后计算他的贡献就可以了,但是没有找到如何在o( ...
- HDU 6058:Kanade's sum(思维)
题目链接 题意 给出一个n和一个k,求1~n的每个区间的第k大的总和是多少,区间长度小于k的话,贡献为0. 思路 首先有一个关系:当一个数是第k大的时候,前面有x个比它大的数,那么后面就有k-x-1个 ...
- HDU - 6058 Kanade's sum
Bryce1010模板 http://acm.hdu.edu.cn/showproblem.php?pid=6058 /* 思路是:找出每个x为第k大的区间个数有多少 用pos[i]保存当前x的位置, ...
- 【链表】2017多校训练三 HDU 6058 Kanade's sum
acm.hdu.edu.cn/showproblem.php?pid=6058 [题意] 给定一个排列,计算 [思路] 计算排列A中每个数的贡献,即对于每个ai,计算有ni个区间满足ai是区间中的第k ...
- hdu 4883 思维题
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4883 TIANKENG’s restaurant Time Limit: 2000/1000 MS (Ja ...
- hdu 5014 思维题/推理
http://acm.hdu.edu.cn/showproblem.php?pid=5014 从小数開始模拟找方法规律,然后推广,尤其敢猜敢尝试,错了一种思路继续猜-----这是一种非常重要的方法啊 ...
随机推荐
- 20175313 张黎仙《Java程序设计》第十一周学习总结
目录 一.教材学习内容总结 二.教材学习中的问题和解决过程 三.代码托管 四.心得体会 五.学习进度条 六.参考资料 一.教材学习内容总结 第十三章内容 主要内容 URL类 InetAdress类 套 ...
- Colab 实用教程
Google Colab 是什么? Google Colab 是一个免费的云服务,现在它还支持免费的 GPU! 你可以: 提高你的 Python 语言的编码技能. 使用 Keras.TensorFlo ...
- IDEA中log4j.properties配置文件详解
配置实例 ### 配置根 ### log4j.rootLogger = debug,console ,fileAppender,dailyRollingFile,ROLLING_FILE,MAIL,D ...
- kotlin泛型中星号投射
如果一个泛型类型中存在多个类型的参数,那么每个类型的参数都可以单独投射,例如:如果类型定义为:"interface Function<in T,out>",那么可以出现 ...
- kafka----简单的脚本命令重点
kafka命令如下: kafka-shell基本命令 在节点hadoop-2,hadoop-3,hadoop-5,启动kafka 启动命令如下 kafka-server-start.sh /usr/l ...
- Oracle查询序列和函数方法封装
工具方法: @Autowired private JdbcTemplate businessTpmeJdbcTemplate; @SuppressWarnings("deprecation& ...
- windows和Linux下定时启动或关闭服务
http://blog.csdn.net/clare504/article/details/17410643 1.Windows下的定时启动程序可以采用系统的计划和任务,定时启动服务可以在计划任务中添 ...
- Flutter的布局方法
重点是什么? Widgets 是用于构建UI的类. Widgets 用于布局和UI元素. 通过简单的widget来构建复杂的widget Flutter布局机制的核心就是widget.在Flutter ...
- 学习Yii(2)
Yii拥有很好的手册,还是中文的,官方的手册很详细.还是应该好好看一下.今天就开始跟着项目代码调试. 上次看到入口脚本,学习一定要快,要用心,抓住时间.不然时间拖久了就忘了.延续不上,大打折扣.而且要 ...
- C++通过Swig跨线程回调Python代码
C++ 定义 Callback 类. PyThreadStateLock 保证垮线程调用成功: #include <Python/Python.h> class Callback { pu ...