zoukankan      html  css  js  c++  java
  • 洛谷P3503 [POI2010]KLO-Blocks 单调栈

    洛谷P3503 [POI2010]KLO-Blocks
    单调栈
    首先 因为每个数都要大于k 所以说,我们就可以先将每一个数减去k,
    然后求他们 的前缀和, 这样问题就转化成了求sum[ r ] - sum[ l ] 运用前缀和
    然后 这样的长度 就是 r-l
    然后我们考虑怎么求这个最大
    首先我们发现 当 i < j 且 sum[ i ] < sum[ j ] 那么 i 一定是 优于 j 的
    所以 我们就可以把这些 j 给 忽略 掉了
    也就是说 我们 开个单调栈 在 i < j 的情况下 保持 sum[ i ] 降序
    然后 我们 从 右向左枚举 r 我们发现在 r 枚举过去时 为了保证答案的最优性
    我们的 l 也必须 时 单调的 ,单调下降 这样以确保答案的最优性

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <iostream> 
     8 #include <iomanip> 
     9 #define ll long long 
    10 using namespace std ; 
    11 
    12 const int maxn = 1000011 ; 
    13 int n,m,x,top,ans ; 
    14 int stack[maxn],a[maxn] ;
    15 ll sum[maxn] ; 
    16 
    17 inline ll read() 
    18 {
    19     ll x = 0 , f = 1 ;  
    20     char ch = getchar() ; 
    21     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; }  
    22     while(ch>='0'&&ch<='9') { x = x * 10+ch-48 ; ch = getchar() ; } 
    23     return x * f ;     
    24 }
    25 
    26 inline ll write(ll x ) 
    27 {
    28     while(x<0) x = -x,putchar('-') ; 
    29     if(x>9) write(x/10) ;  
    30     putchar(x % 10 +48) ; 
    31 }
    32 
    33 inline void solve(int x) 
    34 {
    35     int j ; 
    36     ans = 0 ; 
    37     for(int i=1;i<=n;i++) 
    38         sum[ i ] = sum[ i-1 ] + a[ i ] -x ; 
    39     stack[ 0 ] = 0 ; 
    40     top = 0 ; 
    41     for(int i=1;i<=n;i++) 
    42         if(sum[ stack[top] ] > sum[ i ]) 
    43             stack[++top] = i ; 
    44     j = top + 1 ; 
    45     for(int i=n;i>=1;i--) 
    46     {
    47         while ( j && sum[ i ] >= sum[ stack[ j-1 ] ] ) j-- ; 
    48         ans = max( i - stack[ j ],ans ) ; 
    49     }
    50     write(ans) ; 
    51     putchar(' ') ; 
    52 }
    53 
    54 int main() 
    55 {
    56     n = read() ;   m = read() ; 
    57     for(int i=1;i<=n;i++) 
    58         a[ i ] = read() ; 
    59     for(int i=1;i<=m;i++) 
    60     {
    61         x = read() ; 
    62         solve(x) ; 
    63     }
    64     
    65     return 0 ; 
    66 }
  • 相关阅读:
    Java单例模式:为什么我强烈推荐你用枚举来实现单例模式
    为什么阿里Java规约要求谨慎修改serialVersionUID字段
    使用MyCat实现MySQL读写分离
    你知道HTTP协议的ETag是干什么的吗?
    在centos7中安装MySQL5.7
    MySQL实现主从复制功能
    Leetcode题目169.求众数(简单)
    Leetcode题目160.相交链表(简单)
    Leetcode题目155.最小栈(简单)
    Leetcode题目152.乘积最大子序列(动态规划-中等)
  • 原文地址:https://www.cnblogs.com/third2333/p/7106065.html
Copyright © 2011-2022 走看看