zoukankan      html  css  js  c++  java
  • [BZOJ3613][Heoi2014]南园满地堆轻絮 二分答案

    Description

    小 Z 是 ZRP(Zombies’ Republic of Poetry,僵尸诗歌共和国)的一名诗歌爱好者,最近 他研究起了诗词音律的问题。
      在过去,诗词是需要编成曲子唱出来的,比如下面这首《菩萨蛮》,唱出来的话其对应 的音符就是这样的:
       南  园  满 地 堆 轻 絮, 愁 闻 一 霎 清 明 雨
       1   1  5 5 6 6 5  4 4 3 3 2 2 1  
    因而可以发现,“1 1 5 5 6 6 5 4 4 3 3 2 2 1”这串音符就成为了研究音律的关键。
     小 Z 翻阅了众多史料发现,过去的一首曲子的音调是不下降的 
     小 Z 想要知道对于一首给定的曲子,如何通过提高音调或者降低音调,将它的音调修改 的不下降,
    而且使得修改幅度最大的那个音符的修改幅度尽量小。
    即如果把一个包含 n 个音 符的曲子看做是一个正整数数列 A[1]…A[n],
    那么 目标是求另一个正整数数列 B[1]…B[n], 使得对于任意的 1≤i<n 有 B[i] ≤B[i+1],
    而且使得 Ans = Max{|A[j]-B[j]|,1≤j≤n}尽量 小。  小 Z 很快就想清楚了做法,但是鉴于他还忙着写诗,
    所以这个任务就交给了你。 
     

    Input

    由于数据规模可能较大,因此采用如下方式生成数据。

     每个数据包含 6 个数:n,Sa,Sb,Sc,Sd,A[1],Mod,意为共有 n 个音符,第一个音符为 A[1]。
     生成规则如下: 定义生成函数 F(x) = Sa*x^3 + Sb*x^2 + Sc*x + Sd; 
    那么给出递推公式 A[i] = F(A[i-1]) + F(A[i-2]),此处规定 A[0] = 0. 
    由于中间过程的数可能会特别大,所以要求每一步与 A 中的每个数都对一个给定的数 Mod 取模。
     

    Output

    输出一行,包含一个正整数 Ans。 

     

    Sample Input

    3 815 6901 3839 178 199 10007

    Sample Output

    1334

    HINT

    n≤5000000 

    对于 100%的数据, Sa,Sb,Sc,Sd,A[1] ≤10000, Mod≤1000000007 
     
    样例中生成的数列为:  

    199 4568 1901,此时将 4568 修改为 3234,1901 也修改为 3234 即可,代价为 1334。 

    Solution

    二分答案暴力判断啊...

    二分最后的答案,$check$的时候更新一个$max(a[i]-x,mx)$,如果$a[i]+x$都比目前的$mx$小的话显然就无法构成不下降序列了

    还有一点就是一定要注意乘法的溢出,$1ll$和$mod$要多用几个

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std ;
    
    #define N 5000010
    int n , sa , sb , sc ,sd , mod ;
    int a[ N ] ;
    
    int F( int x ) {
        return ( ( ( 1ll * sa * x % mod * x % mod * x % mod + 1ll * sb * x % mod * x % mod ) % mod + 1ll * sc * x % mod ) % mod + 1ll * sd % mod ) % mod ;
    }
    
    bool check( int x ) {
        int mx = 0 ; 
        for( int i = 1 ; i <= n ; i ++ ) {
            mx = std::max( mx , a[ i ] - x ) ;
            if( a[ i ] + x < mx ) return 0 ;
        }
        return 1 ;
    }
    
    int main() {
        scanf( "%d%d%d%d%d%d%d" , &n , &sa , &sb , &sc , &sd , &a[ 1 ] , &mod ) ;
        a[ 0 ] = 0 ;
        for( int i = 2 ; i <= n ; i ++ ) {
            a[ i ] = F( a[ i - 1 ] ) + F( a[ i - 2 ] ) ;
            a[ i ] = a[ i ] % mod ;
        }
        int l = 0 , r = mod , ans = mod ;
        while( l <= r ) {
            int mid = ( l + r ) >> 1 ;
            if( check( mid ) ) r = mid - 1 , ans = mid ;
            else l = mid + 1 ;
        }
        printf( "%d
    " , ans ) ;
    }
  • 相关阅读:
    Core Animation 文档翻译—附录C(KVC扩展)
    Core Animation 文档翻译—附录B(可动画的属性)
    Core Animation 文档翻译—附录A(Layer样貌相关属性动画)
    Core Animation 文档翻译 (第八篇)—提高动画的性能
    Core Animation 文档翻译 (第七篇)—改变Layer的默认动画
    Core Animation 文档翻译 (第六篇)—高级动画技巧
    Core Animation 文档翻译 (第五篇)—构建Layer的层次结构
    用Markdown快速排版一片文章
    Core Animation 文档翻译 (第四篇)—让Layer的content动画起来
    Core Animation 文档翻译(第三篇)—设置Layer对象
  • 原文地址:https://www.cnblogs.com/henry-1202/p/bzoj3613.html
Copyright © 2011-2022 走看看