HDU6058 Kanade's sum(思维 链表)
Kanade's sum
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 871 Accepted Submission(s): 357
Let f(l,r,k) be the k-th largest element of A[l..r].
Specially , f(l,r,k)=0 if r−l+1<k.
Give you k , you need to calculate ∑nl=1∑nr=lf(l,r,k)
There are T test cases.
1≤T≤10
k≤min(n,80)
A[1..n] is a permutation of [1..n]
∑n≤5∗105
For each test case,there are only two integers n,k on first line,and the second line consists of n integers which means the array A[1..n]
5 2
1 2 3 4 5
【题意】给你一个序列,(1~n的一个全排列),然后询问所有的子区间第k大的数,累加起来,如果区间长度不足k,则为0,求累加 和。
【分析】由于区间数量太多,我们考虑算每个数的贡献。一个数的贡献显然就是它所能存在的区间数量,在这些区间内它是第k大。首先,要保证它是这个区间里的第k大,那么我们必须在他左边和右边找到共k-1个比他大的,然后围成区间就行。我们可以再这个数左边找到最多k个比他大的,右边找到最多k个比他大的(如果存在k个的话)。比如x是当前枚举的数,k=3,a,b,c是左边比他大的数的位置,d,e,f是右边比他大的数的位置(都是位置离x最近的),现在就是这样a b c x d e f,那么现在x的贡献就是能够围成的所有合法区间的数量,比如我们可以左边取x,右边取d e,那么此时的贡献就是(x-c)*(f-e),也可以左边取c,x,右边取d,此时的贡献就是(c-b)*(e-d)...
这样我们把贡献累加起来就是了,但是现在的问题是如何找这k个数。
我们发现当我们枚举到x时,找k个数是直接跨过了比x小的数,直接跳到了比x大的,所以我们可以从小到大枚举x,用一个链表把所有比x大的数连起来,当我们处理完x的时候,我们就把x的位置从链表里删除,这样我们的链表里存的都是比x大的数,而且相对位置也没变。这样我们就是O(k)找到这k个数.总时间复杂度,O(n*k)。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long ll;
const int N = 5e5+;;
const int M = ;
const int mod = 1e9+;
const double pi= acos(-1.0);
typedef pair<int,int>pii;
int n,k;
int pos[N],pre[N],suf[N];
int l[N],r[N];
void del(int x){
int pree=pre[x];
int suff=suf[x];
if(pree)suf[pree]=suff;
if(suff<=n)pre[suff]=pree;
pre[x]=suf[x]=;
}
int main() {
int T;
scanf("%d",&T);
while(T--){
ll ans=;
scanf("%d%d",&n,&k);
for(int i=,x;i<=n;i++){
scanf("%d",&x);
pos[x]=i;
}
for(int i=;i<=n;i++){
pre[i]=i-;
suf[i]=i+;
}
for(int x=;x<=n-k+;x++){
l[]=r[]=;
int p=pos[x];
for(int i=p;i&&l[]<=k+;i=pre[i])l[++l[]]=i;
for(int i=p;i<n+&&r[]<=k+;i=suf[i])r[++r[]]=i;
l[++l[]]=;
r[++r[]]=n+;
for(int i=;i<l[];i++){
if(i+r[]>=k+&&i<=k){
ans+=1LL*(l[i]-l[i+])*1LL*(r[k-i+]-r[k-i+])*x;
}
}
del(p);
}
printf("%lld\n",ans);
}
return ;
}
HDU6058 Kanade's sum(思维 链表)的更多相关文章
- hdu6058 Kanade's sum 区间第k大
/** 题目:Kanade's sum 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题意:给定[1,n]的排列,定义f(l,r,k)表示区间[l ...
- 【set】【链表】hdu6058 Kanade's sum
f(l,r,K)表示区间l,r里面的K大值,问你所有连续子区间的f之和. l(i)表示i左侧第一个比它大的数的位置,r(i)表示i右侧第一个比它大的数的位置.可以用set处理出来. 把数从大到小排序, ...
- hdu-6058 Kanade's sum
题意:略 思路:要我们求每个区间第K大数之和,其实可以转换为求多少个区间的第K大数是X,然后我们在求和就好了. 那么我们可以从小到大枚举所有可能成为第K大的数.为什么从小到大呢? 因为从小到大我们就略 ...
- 2017 Multi-University Training Contest - Team 3—HDU6058 Kanade's sum
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题目意思:给你一个排列,求所有区间长度大于等于k的区间第k大的数的和…… 思路:一开始看到区间k ...
- 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 6058 Kanade's sum(模拟链表)
Kanade's sum Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- 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 ...
- 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 ...
- HDU 6058 Kanade's sum —— 2017 Multi-University Training 3
Kanade's sum Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
随机推荐
- vijos 1426 背包+hash
背景 北京奥运会开幕了,这是中国人的骄傲和自豪,中国健儿在运动场上已经创造了一个又一个辉煌,super pig也不例外……………… 描述 虽然兴奋剂是奥运会及其他重要比赛的禁药,是禁止服用的.但是运动 ...
- POJ 2891- Strange Way to Express Integers CRT 除数非互质
题意:给你余数和除数求x 注意除数不一定互质 思路:不互质的CRT需要的是将两个余数方程合并,需要用到扩展GCD的性质 合并互质求余方程 m1x -+ m2y = r2 - r1 先用exgcd求出特 ...
- 【C++对象模型】第五章 构造、解构、拷贝 语意学
1.构造语义学 C++的构造函数可能内带大量的隐藏码,因为编译器会扩充每一个构造函数,扩充程度视 class 的继承体系而定.一般而言编译器所做的扩充操作大约如下: 所有虚基类成员构造函数必须被调用, ...
- PowerDesigner16 修改表或表的字段Name的时候不让Code不自动跟着变
在修改表或表的字段Name的时候不让Code不自动跟着变,设置如下: tools-> General Options-> Dialog 去掉勾选 Name To Code mirror ...
- MyBatis框架的使用及源码分析(十二) ParameterHandler
在StatementHandler使用prepare()方法后,接下来就是使用ParameterHandler来设置参数,让我们看看它的定义: package org.apache.ibatis.ex ...
- 【BZOJ】1385 [Baltic2000]Division expression
[算法]欧几里德算法 [题解]紫书原题 #include<cstdio> #include<algorithm> using namespace std; ; int T,t, ...
- bzoj 2669 状压DP
因为最多有8个'X',所以我们可以用w[i][s]来表示现在我们填了前i个数,填的X的为S,因为每次新加进来的数都不影响前面的最小值,所以我们可以随便添加,这样就有了剩下所有位置的方案,每次都这样转移 ...
- 关于ssh三大框架整合的碎碎念
三大框架整合,无非就是一个导jar包,修改配置文件的过程.完了就没事了. 还是有很多细节性的问题 比如在spring中写applicationContext.xml文件时不提示: 解决方法如下: 如果 ...
- spring boot 注解说明
Starters 可以创建自己的Starter,但名字格式不能是 spring-boot-starter-*,而是 *-spring-boot-starter.类似Maven插件的规则. 自动配置 ...
- TensorFlow中get_variable共享变量调用
import tensorflow as tf with tf.variable_scope('v_scope',reuse=True) as scope1: Weights1 = tf.get_va ...