zoukankan      html  css  js  c++  java
  • TYVJ1427 小白逛公园

    P1427 小白逛公园
    时间: 1000ms / 空间: 131072KiB / Java类名: Main

    描述

        小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了。
        一开始,小白就根据公园的风景给每个公园打了分-.-。小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第a个和第b个公园之间(包括a、b两个公园)选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。同时,由于一些公园的景观会有所改变,所以,小白的打分也可能会有一些变化。
        那么,就请你来帮小白选择公园吧。

    输入格式

        第一行,两个整数N和M,分别表示表示公园的数量和操作(遛狗或者改变打分)总数。
        接下来N行,每行一个整数,依次给出小白 开始时对公园的打分。
        接 下来M行,每行三个整数。第一个整数K,1或2。K=1表示,小新要带小白出去玩,接下来的两个整数a和b给出了选择公园的范围 (1≤a,b≤N);K=2表示,小白改变了对某个公园的打分,接下来的两个整数p和s,表示小白对第p个公园的打分变成了s(1≤p≤N)。
        其中,1≤N≤500 000,1≤M≤100 000,所有打分都是绝对值不超过1000的整数。

    输出格式

        小白每出去玩一次,都对应输出一行,只包含一个整数,表示小白可以选出的公园得分和的最大值。

    测试样例1

    输入

    5 3
    1 2 -3 4 5
    1 2 3
    2 2 -1
    1 2 3

    输出

    2
    -1
    【题解】
    线段树裸题,维护前缀最大,后缀最大,最大子区间和区间和
    查询的是偶发,维护  当前区间在查询区间范围内的  前缀最大,后缀最大,最大子区间和区间和
    注意这个题,有一种情况,叫l > r,要交换过来(淦
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #define max(a, b) ((a) > (b) ? (a) :(b))
      6 #define min(a, b) ((a) < (b) ? (a) : (b)) 
      7 
      8 inline void read(int &x)
      9 {
     10     x = 0;char ch = getchar(), c = ch;
     11     while(ch < '0' || ch > '9')c = ch, ch = getchar();
     12     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     13     if(c == '-')x = -x;
     14 }
     15 
     16 inline void swap(int &a, int &b)
     17 {
     18     int tmp = a;
     19     a = b,b = tmp;
     20 } 
     21 
     22 const int MAXN = 600000 + 10;
     23 const int INF = 0x3f3f3f3f3f3f3f3f;
     24 
     25 int n,m,num[MAXN];
     26 
     27 int left[MAXN << 2], right[MAXN << 2], sum[MAXN << 2], ma[MAXN << 2];
     28 
     29 void build(int o = 1, int l = 1, int r = n)
     30 {
     31     if(l == r)
     32     {
     33         left[o] = right[o] = sum[o] = ma[o] = num[l];
     34         return;
     35     }
     36     int mid = (l + r) >> 1;
     37     build(o << 1, l, mid);
     38     build(o << 1 | 1, mid + 1, r);
     39     
     40     left[o] = max(left[o << 1], sum[o << 1] + left[o << 1 | 1]);    
     41     right[o] = max(right[o << 1 | 1], sum[o << 1 | 1] + right[o << 1]);
     42     ma[o] = max(ma[o << 1], max(ma[o << 1 | 1], right[o << 1] + left[o << 1 | 1]));
     43     ma[o] = max(ma[o], max(left[o], right[o]));
     44     sum[o] = sum[o << 1] + sum[o << 1 | 1];
     45 }
     46 
     47 void modify(int p, int k, int o = 1, int l = 1, int r = n)
     48 {
     49     if(l == p && l == r)
     50     {
     51         left[o] = right[o] = sum[o] = ma[o] = k;
     52         return;
     53     }
     54     int mid = (l + r) >> 1;
     55     if(mid >= p)modify(p, k, o << 1, l, mid);
     56     else modify(p, k, o << 1 | 1, mid + 1, r);
     57     
     58     left[o] = max(left[o << 1], sum[o << 1] + left[o << 1 | 1]);    
     59     right[o] = max(right[o << 1 | 1], sum[o << 1 | 1] + right[o << 1]);
     60     ma[o] = max(ma[o << 1], max(ma[o << 1 | 1], right[o << 1] + left[o << 1 | 1]));
     61     ma[o] = max(ma[o], max(left[o], right[o]));
     62     sum[o] = sum[o << 1] + sum[o << 1 | 1];
     63 }
     64 
     65 struct Node
     66 {
     67     int left, right, ma, sum;
     68     Node(int _left, int _right, int _ma, int _sum){left = _left, right = _right, ma = _ma, sum = _sum;}
     69     Node(){left = right = ma = -INF;sum = 0;}    
     70 };
     71 
     72 Node ask(int ll, int rr, int o = 1, int l = 1, int r = n)
     73 {
     74     if(ll <= l && rr >= r)return Node(left[o], right[o], ma[o], sum[o]);
     75     int mid = (l + r) >> 1;
     76     Node re, ans1, ans2;
     77     int flag1 = 0, flag2 = 0;
     78     if(mid >= ll)ans1 = ask(ll, rr, o << 1, l, mid), flag1 = 1;
     79     if(mid < rr)ans2 = ask(ll, rr, o << 1 | 1, mid + 1, r), flag2 = 1;
     80     
     81     re.left = max(ans1.left, ans1.sum + ans2.left);
     82     if(!flag1)    re.left = max(re.left, ans2.left);
     83     
     84     re.right = max(ans2.right, ans2.sum + ans1.right);
     85     if(!flag2)    re.right = max(ans2.right, re.right);
     86     
     87     re.ma = max(re.left, max(re.right, ans1.right + ans2.left));
     88     re.ma = max(re.ma, max(ans1.ma, ans2.ma));
     89     re.sum = ans1.sum + ans2.sum;
     90     return re;
     91 }
     92 
     93 int main()
     94 {
     95     read(n), read(m);
     96     for(register int i = 1;i <= n;++ i) read(num[i]);
     97     memset(left, -0x3f, sizeof(left));
     98     memset(right, -0x3f, sizeof(left));
     99     memset(ma, -0x3f, sizeof(left));
    100     build(1,1,n); 
    101     register int tmp1,tmp2,tmp3;
    102     register Node tmp;
    103     for(register int i = 1;i <= m;++ i)
    104     {
    105         read(tmp1), read(tmp2), read(tmp3);
    106         if(tmp1 == 1) 
    107         {
    108             if(tmp2 > tmp3)swap(tmp2, tmp3); 
    109             tmp = ask(tmp2, tmp3, 1, 1, n);
    110             printf("%d
    ", tmp.ma);
    111         }
    112         else modify(tmp2, tmp3, 1, 1, n);
    113     }
    114     return 0;
    115 } 
    TYVJ1427
  • 相关阅读:
    Android内存管理之道
    What a C programmer should know about memory
    Android Bitmap缓存池使用详解
    android 5.0主题风格研究
    最受欢迎的5个Android ORM框架
    目前具体实现 material design 有什么途径?
    计算机的数学要求(?转)
    机器智能公司一览图 | 36氪
    Android中Context
    从源码的角度深入分析Scroller
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7482830.html
Copyright © 2011-2022 走看看