zoukankan      html  css  js  c++  java
  • codeforces332B

    题意:给你一个序列,找两个长度为 k 且没有重合区间的数使得其和最大

    解题思路:

    1)线段树

    想了半天想不出只能先用线段树撸了一发,这题dp 第一名只要了 9分钟。

    就是把起点为 i  长度为 k 的和预处理出来,再用线段树枚举去找。

    解题代码:

      1 // File Name: 332b.cpp
      2 // Author: darkdream
      3 // Created Time: 2014年07月30日 星期三 08时10分45秒
      4 
      5 #include<vector>
      6 #include<list>
      7 #include<map>
      8 #include<set>
      9 #include<deque>
     10 #include<stack>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<functional>
     14 #include<numeric>
     15 #include<utility>
     16 #include<sstream>
     17 #include<iostream>
     18 #include<iomanip>
     19 #include<cstdio>
     20 #include<cmath>
     21 #include<cstdlib>
     22 #include<cstring>
     23 #include<ctime>
     24 #define LL long long 
     25 using namespace std;
     26 #define M 200004
     27 struct node{
     28   int l , r ,m; 
     29   LL maxn,s; 
     30 }tree[M <<2];
     31 LL a[200004];
     32 LL sum[200004];
     33 int L(int x)
     34 {
     35   return 2 * x; 
     36 }
     37 int R(int x)
     38 {
     39    return 2 * x + 1; 
     40 }
     41 void  pushup(int c)
     42 {
     43    if(tree[L(c)].maxn >=tree[R(c)].maxn)
     44    {
     45       tree[c].maxn = tree[L(c)].maxn;
     46       tree[c].s = tree[L(c)].s;
     47    }else{
     48       tree[c].maxn = tree[R(c)].maxn;
     49       tree[c].s = tree[R(c)].s;
     50    }
     51 }
     52 void build(int c ,int l, int r)
     53 {
     54       tree[c].l = l ;
     55       tree[c].r = r ;
     56       tree[c].m = (l+r)/2;
     57       if(l == r)
     58       {
     59         tree[c].maxn = sum[l]; 
     60         tree[c].s = l ; 
     61         return ; 
     62       }
     63       build(L(c),l,tree[c].m);
     64       build(R(c),tree[c].m+1,r);
     65       pushup(c);
     66 }
     67 LL maxa; 
     68 int site;
     69 void find(int c, int l , int r)
     70 {
     71     //printf("%d %d %d %d %d
    ",c,tree[c].l,tree[c].r,l,r);
     72      if(r <  l )
     73          return ; 
     74      if(l <= tree[c].l && r >= tree[c].r)
     75      {
     76          if(tree[c].maxn > maxa)
     77          {
     78            maxa = tree[c].maxn;
     79            site = tree[c].s; 
     80          }
     81          return ;
     82      }
     83      if(l <= tree[c].m)
     84          find(L(c),l,r);
     85      if(r > tree[c].m)
     86          find(R(c),l,r);
     87 }
     88 int main(){
     89    int n , k;
     90    scanf("%d %d",&n,&k);
     91    int temp ;
     92    a[0] = 0 ; 
     93    for(int i = 1; i <= n;i ++)
     94    {
     95        scanf("%d",&temp);
     96        a[i] = a[i-1] + temp;
     97    }
     98    for(int i = 1 ;i <= n-k+1; i ++)
     99    {
    100       sum[i] = a[i+k-1] - a[i-1];
    101    }
    102    build(1,1,n-k+1);
    103    LL  ans = -1e9;
    104    int a, b ; 
    105    for(int i =1 ;i <= n-k+1;i ++)
    106    {
    107       maxa = -1e9 ;
    108       site = 0 ; 
    109       find(1,i+k,n-k+1);
    110       if(sum[i] + maxa > ans)
    111       {
    112           ans  = sum[i] + maxa;
    113           a= i ; 
    114           b = site;
    115       }
    116    }
    117    printf("%d %d
    ",a,b);
    118 return 0;
    119 }
    View Code

     2)由第一种思路突然想到还可以预处理出来 i 以后 的最大值是多少,位置是多少,这样就可以直接dp了

     1 // File Name: 332b.1.cpp
     2 // Author: darkdream
     3 // Created Time: 2014年07月30日 星期三 10时13分41秒
     4 
     5 #include<vector>
     6 #include<list>
     7 #include<map>
     8 #include<set>
     9 #include<deque>
    10 #include<stack>
    11 #include<bitset>
    12 #include<algorithm>
    13 #include<functional>
    14 #include<numeric>
    15 #include<utility>
    16 #include<sstream>
    17 #include<iostream>
    18 #include<iomanip>
    19 #include<cstdio>
    20 #include<cmath>
    21 #include<cstdlib>
    22 #include<cstring>
    23 #include<ctime>
    24 #define LL long long 
    25 #define maxn 200050 
    26 using namespace std;
    27 LL a[maxn];
    28 LL sum[maxn];
    29 LL m[maxn];
    30 int s[maxn];
    31 int n , k ; 
    32 int main(){
    33      scanf("%d %d",&n,&k);
    34      a[0] = 0 ; 
    35      int temp ; 
    36      for(int i = 1;i <=  n;i ++)
    37      {
    38         scanf("%d",&temp);
    39         a[i] =a[i-1]+ temp; 
    40      }
    41      int p = n - k + 1; 
    42      for(int i = 1;i <= p ; i ++)
    43      {
    44        sum[i] = a[i+k-1] - a[i-1];
    45      }
    46      m[p] = sum[p];
    47      s[p] = p ; 
    48     
    49      for(int i = p -1;i >= 1 ;i --)
    50      {
    51         if(sum[i] >= m[i+1])
    52         {
    53             m[i] = sum[i];
    54             s[i] = i ;
    55         }else{
    56            m[i] = m[i+1];
    57            s[i] = s[i+1];
    58         }
    59      }
    60      int a, b ;
    61      LL maxa = -1e9 ; 
    62      for(int i =1 ;i <= p;i ++)
    63      {
    64         if(sum[i] + m[i+k] > maxa) 
    65         {
    66            a = i ; 
    67            b = s[i+k];
    68            maxa = sum[i] + m[i+k];
    69         }
    70      }
    71      printf("%d %d
    ",a,b);
    72 return 0;
    73 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    查找 Search
    [HEOI2016/TJOI2016]排序
    [SDOI2011\]染色
    [构造题选讲]
    [LNOI2014]LCA
    [POI2013]LUKTriumphal arch
    java取得某月最后一天
    设置上网代理服务器
    Richfaces改变我的编程方式
    Richfaces Style
  • 原文地址:https://www.cnblogs.com/zyue/p/3877286.html
Copyright © 2011-2022 走看看