zoukankan      html  css  js  c++  java
  • 【8.15校内测试】【队列】【manacher】

    dp??不能确定转移状态。考虑用优先队列储存最优决策点,可是发现当前选择最优不能保证最后最优,在后面可以将之前用过的替换过来。

    比如数据:

    3 5

    4 6

    只储存a[i]来决策不能延展到后面的状态,因此每次选择过后把b[i]加入队列,下次选择最优时如果选择到了b[i],则表示用之前选择过的来替换到当前状态。

    这里我开了两个优先队列。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #define ll long long
     5 #define RG register
     6 using namespace std;
     7 
     8 int n, a[100005], b[100005];
     9 
    10 priority_queue < int, vector < int > , greater < int > > q1, q2;
    11 
    12 int main ( ) {
    13     freopen ( "buy.in", "r", stdin );
    14     freopen ( "buy.out", "w", stdout );
    15     scanf ( "%d", &n );
    16     for ( RG int i = 1; i <= n; i ++ )
    17         scanf ( "%d", &a[i] );
    18     for ( RG int i = 1; i <= n; i ++ )
    19         scanf ( "%d", &b[i] );
    20     ll ans = 0;
    21     for ( RG int i = 1; i <= n; i ++ ) {
    22         q1.push ( a[i] );
    23         int r1 = 0, r2 = 0;
    24         if ( !q1.empty ( ) ) {
    25             int x = q1.top ( );
    26             if ( b[i] > x ) r1 = b[i] - x;
    27         }
    28         if ( !q2.empty ( ) ) {
    29             int x = q2.top ( );
    30             if ( b[i] > x ) r2 = b[i] - x;
    31         }
    32 if ( r1 >= r2 && r1 ) ans += r1, q1.pop ( ), q2.push ( b[i] ); 33 else if ( r2 > r1 && r2 ) ans += r2, q2.pop ( ), q2.push ( b[i] ); 34 } 35 printf ( "%I64d", ans ); 36 return 0; 37 }

    记录前缀和,可以发现,从某一个点为起点时,向后延展出去的长度中一定有i到i+s这一段,所以用前缀和最大值建一棵线段树,每次查找i+s-1到i+e-1段的最大值,减去i-1的前缀和比较答案即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #define ll long long 
     4 using namespace std;
     5 
     6 int n, s, e, a[100005];
     7 ll pre[100005], TR[400005];
     8 
     9 void update ( int nd ) {
    10     TR[nd] = max ( TR[nd << 1], TR[nd << 1 | 1] );
    11 }
    12 
    13 void build ( int nd, int l, int r ) {
    14     if ( l == r ) {
    15         TR[nd] = pre[l];
    16         return ;
    17     }
    18     int mid = ( l + r ) >> 1;
    19     build ( nd << 1, l, mid );
    20     build ( nd << 1 | 1, mid + 1, r );
    21     update ( nd );
    22 }
    23 
    24 ll query ( int nd, int l, int r, int L, int R ) {
    25     if ( l >= L && r <= R ) return TR[nd];
    26     int mid = ( l + r ) >> 1;
    27     ll ans = -1e9;
    28     if ( L <= mid ) ans = max ( ans, query ( nd << 1, l, mid, L, R ) );
    29     if ( R > mid ) ans = max ( ans, query ( nd << 1 | 1, mid + 1, r, L, R ) );
    30     return ans;
    31 }
    32 
    33 int main ( ) {
    34     freopen ( "invest.in", "r", stdin );
    35     freopen ( "invest.out", "w", stdout );
    36     scanf ( "%d%d%d", &n, &s, &e );
    37     for ( int i = 1; i <= n; i ++ ) {
    38         scanf ( "%d", &a[i] );
    39         pre[i] = pre[i-1] + a[i];
    40     }
    41     build ( 1, 1, n );
    42     ll ans = 0;
    43     for ( int i = 1; i <= n; i ++ ) {
    44         if ( i + s - 1 > n ) break;
    45         ll x = query ( 1, 1, n, i + s - 1, i + e - 1 );
    46         ans = max ( x - pre[i-1], ans );
    47     }
    48     printf ( "%I64d", ans );
    49     return 0;
    50 }

    关键时候manacher忘了怎么写!!先manacher一遍处理出以每个点为中心点的最长回文串长度,一定是奇数。开桶记录每个长度出现次数,从大到小枚举长度l,每次把l-2的次数加上l的次数,因为l的长度满足回文串l-2一定满足(同一中心点,注意k要开long long!

     1 #include<iostream>
     2 #include<cstdio>
     3 #define ll long long
     4 #define mod 19930726
     5 using namespace std;
     6 
     7 ll max_r[2000005];
     8 int n;
     9 ll k;
    10 ll ans = 1, flag[1000005];
    11 
    12 char M[2000005], a[1000005];
    13 
    14 inline ll min ( ll a, int b ) {
    15     return a < b ? a : b;
    16 }
    17 
    18 ll mi ( ll a, ll b ) {
    19     ll an = 1;
    20     for ( ; b; b >>= 1, a = a * a % mod )
    21         if ( b & 1 ) an = an * a % mod;
    22     return an;
    23 }
    24 
    25 void manacher ( ) {
    26     M[0] = '@';
    27     for ( int i = 1; i <= n; i ++ ) {
    28         M[2 * i - 1] = '#';
    29         M[2 * i] = a[i];
    30     }
    31     M[2 * n + 1] = '#'; M[2 * n + 2] = '$';
    32     int center = 0; ll mx = 0;
    33     int side = n * 2 + 1;
    34     for ( int i = 1; i <= n * 2 + 1; i ++ ) {
    35         if ( mx > i ) max_r[i] = min ( mx - (ll)i, max_r[center * 2 - i] );
    36         else max_r[i] = 1;
    37         while ( M[max_r[i]+i] == M[i-max_r[i]] ) max_r[i] ++;
    38         if ( mx < i + max_r[i] ) {
    39             mx = i + max_r[i]; center = i;
    40         }
    41     }
    42 }
    43 
    44 int main ( ) {
    45     freopen ( "rehearse.in", "r", stdin );
    46     freopen ( "rehearse.out", "w", stdout );
    47     scanf ( "%d%I64d
    ", &n, &k );
    48     scanf ( "%s", a + 1 );
    49     manacher ( );
    50     ll MA = 0;
    51     for ( int i = 1; i <= n; i ++ ) {
    52         max_r[i*2] --;
    53         flag[max_r[i*2]] ++;
    54         MA = max ( MA, max_r[i*2] );
    55     }
    56     ll pos = MA;
    57     while ( k > 0 ) {
    58         ans = ( ans * mi ( pos, min ( flag[pos], k ) ) ) % mod;
    59         flag[pos-2] += flag[pos];
    60         k -= flag[pos];
    61         pos = pos - 2;
    62     }
    63     printf ( "%I64d", ans );
    64     return 0;
    65 }
  • 相关阅读:
    Lambda表达式、依赖倒置
    ASP.NET vNext 概述
    Uname
    RHEL4 i386下安装rdesktop【原创】
    Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)
    How to decompile class file in Java and Eclipse
    先有的资源,能看的速度看,不能看的,抽时间看。说不定那天就真的打不开了(转)
    Google App Engine 学习和实践
    【VBA研究】VBA通过HTTP协议实现邮件轨迹跟踪查询
    js正則表達式语法
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9484047.html
Copyright © 2011-2022 走看看