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 }
  • 相关阅读:
    Android:使用 DownloadManager 进行版本更新
    Android:UI 沉浸式体验,适合第一屏的引导图片、预览图片。
    Android:相机适配及图片处理的一些问题
    Android: 设置 app 字体大小不跟随系统字体调整而变化
    Android: TextView 及其子类通过代码和 XML 设置字体大小的存在差异的分析
    SQLMap 学习
    我的书单
    macos
    linux BufferedImage.createGraphics()卡住不动
    Linux 中ifconfig和ip addr命令看不到ip
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9484047.html
Copyright © 2011-2022 走看看