hdu5662 YJQQQAQ and the function (单调栈)
2016-04-13 11:20
344 查看
Problem Description
YJQQQAQ has an array A of
length n.
He defines a function fl,r,k where l,r,k are
positive integers that satisfies l≤r and r×k≤n,
and the value of the function equals to p×q×⌊k√⌋ where p equals
to the sum value of Al×k,A(l+1)×k,...,Ar×k and q equals
to the minimal value of them. YJQQQAQ wants to choose the positive integers l,r,k carefully
to maximize the value of the function.
Input
The first line contains an integer T(1≤T≤3)——The
number of the test cases. For each test case:
The first line contains an integers n(1≤n≤300,000).
The second line contains n integers
describing the given array A,
the ith
integer is Ai(1≤Ai≤1,000,000).
Between each two adjacent integers there is a white space separated.
Output
For each test case, the only line contains the only integer that is the maximum value of the function.
Sample Input
1
3
2 3 1
Sample Output
10
题意:给你n个数,你要找到3个数,l,r,k,l<=r,r*k<=n且p*q*sqrt(k)最小,其中p是A[l*k],A[(l+1)*k]...,A[r*k]的和,q是这些数的最小值。
思路:看到求一些数的和乘这些数中最小值的最小值,容易想到单调栈,我们只要先把在k确定的情况下找出所有符合条件的A[],然后再用单调栈找出以每一个数位最小值的左右边界,然后更新ans的最大值就行了。ps:还是不习惯用单调栈,所以用两遍单调队列做了,时间复杂度会差一下,不过差不多。
YJQQQAQ has an array A of
length n.
He defines a function fl,r,k where l,r,k are
positive integers that satisfies l≤r and r×k≤n,
and the value of the function equals to p×q×⌊k√⌋ where p equals
to the sum value of Al×k,A(l+1)×k,...,Ar×k and q equals
to the minimal value of them. YJQQQAQ wants to choose the positive integers l,r,k carefully
to maximize the value of the function.
Input
The first line contains an integer T(1≤T≤3)——The
number of the test cases. For each test case:
The first line contains an integers n(1≤n≤300,000).
The second line contains n integers
describing the given array A,
the ith
integer is Ai(1≤Ai≤1,000,000).
Between each two adjacent integers there is a white space separated.
Output
For each test case, the only line contains the only integer that is the maximum value of the function.
Sample Input
1
3
2 3 1
Sample Output
10
题意:给你n个数,你要找到3个数,l,r,k,l<=r,r*k<=n且p*q*sqrt(k)最小,其中p是A[l*k],A[(l+1)*k]...,A[r*k]的和,q是这些数的最小值。
思路:看到求一些数的和乘这些数中最小值的最小值,容易想到单调栈,我们只要先把在k确定的情况下找出所有符合条件的A[],然后再用单调栈找出以每一个数位最小值的左右边界,然后更新ans的最大值就行了。ps:还是不习惯用单调栈,所以用两遍单调队列做了,时间复杂度会差一下,不过差不多。
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<string> #include<bitset> #include<algorithm> using namespace std; #define lth th<<1 #define rth th<<1|1 typedef long long ll; typedef long double ldb; #define inf 99999999 #define pi acos(-1.0) #define maxn 300050 int b[maxn],a[maxn]; ll sum[maxn]; int L[maxn],R[maxn]; int q[511111][2]; int main() { int n,m,i,j,T,l,r,k; int front,rear; ll ans; scanf("%d",&T); while(T--) { scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&a[i]); } ans=0; for(k=1;k<=n;k++){ int tot=0; sum[0]=0; for(i=1;i*k<=n;i++){ tot++; b[tot]=a[i*k]; sum[tot]=sum[tot-1]+b[tot]; } front=1,rear=0; for(i=1;i<=tot;i++){ while(front<=rear && q[rear][0]>=b[i] ){ rear--; } if(rear==0){ L[i]=1; } else{ L[i]=q[rear][1]+1; } rear++; q[rear][0]=b[i];q[rear][1]=i; } front=1,rear=0; for(i=tot;i>=1;i--){ while(front<=rear && q[rear][0]>=b[i] ){ rear--; } if(rear==0){ R[i]=tot; } else{ R[i]=q[rear][1]-1; } rear++; q[rear][0]=b[i];q[rear][1]=i; ans=max(ans,(sum[R[i] ]-sum[L[i]-1 ])*b[i]*(int)sqrt((double)k) ); } } printf("%lld\n",ans); } return 0; }
相关文章推荐
- 4/13 发布到线上遇到的路径问题
- Asp.net mvc 强类型View
- 【Android】studio中9patch图片只能放在drawable中,不能放mipmap中
- tomcat Server Locations 不可用 两种解决方式
- HDFS源码分析数据块复制之PendingReplicationBlocks
- 六种单例模式
- HTML页面中启动Activity
- ubuntu 生成 .pem 证书连接服务器,取消OpenSSH密钥密码认证
- Unity 控制物体绕x,y,z 轴旋转
- uboot的relocation原理详细分析
- NOI主计划
- Android应用程序文件组成
- Python yield与实现
- leetcode: 链表2
- unity3d插件Daikon Forge GUI 中文教程5-高级控件listbox和progress bar的使用
- 2016腾讯编程题:生成格雷码
- 原生TabLayout使用
- 最快让你上手ReactiveCocoa之进阶篇
- setfacl命令
- 《将博客搬至CSDN》