zoukankan      html  css  js  c++  java
  • 【SPOJ】1557 Can you answer these queries II

    询问区间最大连续和,相同的只能算一次。可以不取,即为0

    线段树在线做不到,只好离线搞。

    一般最大连续和,都是以一个点为起点,往左或往右。其实,还可以以一个点为起点,往上最大是多少。

    用pos标记一个数之前更新到的位置。

    比如:-3 2 -3 1

    用线段树成段覆盖:(越下方越早更新到)

    1       1        1        1

           -3      -3

    2      2

    -3

    nowsum表示当前深度积累的总和。

    nowup表示当前深度从底往上的最大值。

    totsum,totup同理,表示的是以某个叶子为起点对应的值。

    加上读入优化,快了2s……

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<iostream>
      5 #define MAXN 200010
      6 #define S 100000
      7 typedef long long LL;
      8 using namespace std;
      9 struct seg {
     10     int left, right, id;
     11 };
     12 struct node {
     13     LL nowsum, nowup;
     14     LL totsum, totup;
     15 };
     16 seg p[MAXN];
     17 node tree[MAXN << 2];
     18 LL a[MAXN], ans[MAXN];
     19 int pos[MAXN];
     20 inline bool cmp(seg a, seg b) {
     21     return a.right < b.right;
     22 }
     23 inline LL MAX(LL x, LL y) {
     24     return x > y ? x : y;
     25 }
     26 void Build(int L, int R, int rt) {
     27     tree[rt].nowsum = tree[rt].nowup = 0;
     28     tree[rt].totsum = tree[rt].totup = 0;
     29     if (L != R) {
     30         int mid = (L + R) >> 1;
     31         Build(L, mid, rt << 1);
     32         Build(mid + 1, R, rt << 1 | 1);
     33     }
     34 }
     35 inline void PushUp(int rt) {
     36     tree[rt].totsum = MAX(tree[rt << 1].totsum, tree[rt << 1 | 1].totsum)
     37             + tree[rt].nowsum;
     38     tree[rt].totup = MAX(tree[rt << 1].totup, tree[rt << 1 | 1].totup);
     39     tree[rt].totup = MAX(tree[rt].totup,
     40             MAX(tree[rt << 1].totsum, tree[rt << 1 | 1].totsum)
     41                     + tree[rt].nowup);
     42 }
     43 inline void Down(int a, int b) {
     44     tree[b].nowup = MAX(tree[b].nowup, tree[b].nowsum + tree[a].nowup);
     45     tree[b].nowsum += tree[a].nowsum;
     46     PushUp(b);
     47 }
     48 inline void PushDown(int rt) {
     49     Down(rt, rt << 1);
     50     Down(rt, rt << 1 | 1);
     51     tree[rt].nowsum = tree[rt].nowup = 0;
     52 }
     53 void Update(int x, int y, int val, int L, int R, int rt) {
     54     if (x <= L && R <= y) {
     55         tree[rt].nowsum += val;
     56         tree[rt].nowup = MAX(tree[rt].nowup, tree[rt].nowsum);
     57         PushUp(rt);
     58     } else {
     59         int mid = (L + R) >> 1;
     60         PushDown(rt);
     61         if (x <= mid)
     62             Update(x, y, val, L, mid, rt << 1);
     63         if (y > mid)
     64             Update(x, y, val, mid + 1, R, rt << 1 | 1);
     65         PushUp(rt);
     66     }
     67 }
     68 LL Query(int x, int y, int L, int R, int rt) {
     69     if (x <= L && R <= y)
     70         return tree[rt].totup;
     71     else {
     72         int mid = (L + R) >> 1;
     73         LL res = 0;
     74         PushDown(rt);
     75         if (x <= mid)
     76             res = MAX(res, Query(x, y, L, mid, rt << 1));
     77         if (y > mid)
     78             res = MAX(res, Query(x, y, mid + 1, R, rt << 1 | 1));
     79         return res;
     80     }
     81 }
     82 int INT() {
     83     int res;
     84     char ch;
     85     bool neg;
     86     while (ch = getchar_unlocked(), !isdigit(ch) && ch != '-')
     87         ;
     88     if (ch == '-') {
     89         res = 0;
     90         neg = true;
     91     } else {
     92         res = ch - '0';
     93         neg = false;
     94     }
     95     while (ch = getchar_unlocked(), isdigit(ch))
     96         res = res * 10 + ch - '0';
     97     return neg ? -res : res;
     98 }
     99 int main() {
    100     int n, i, j, q;
    101     while (~scanf("%d", &n)) {
    102         Build(1, n, 1);
    103         memset(pos, 0, sizeof(pos));
    104         for (i = 1; i <= n; i++)
    105             a[i] = INT();
    106         q = INT();
    107         for (i = 0; i < q; i++) {
    108             p[i].left = INT(), p[i].right = INT();
    109             p[i].id = i;
    110         }
    111         sort(p, p + q, cmp);
    112         for (i = 1, j = 0; i <= n && j < q; i++) {
    113             Update(pos[a[i] + S] + 1, i, a[i], 1, n, 1);
    114             pos[a[i] + S] = i;
    115             for (; j < q && i == p[j].right; j++)
    116                 ans[p[j].id] = Query(p[j].left, p[j].right, 1, n, 1);
    117         }
    118         for (i = 0; i < q; i++)
    119             printf("%lld\n", ans[i]);
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    rancher 2.X 搭建小型web集群+mysql主从复制
    harbor 仓库搭建
    k8s 集群搭建
    oracle sql命令
    IIS实现反向代理
    高并发的大型网站架构设计
    .net core集成vue
    使用TFS玩转Docker自动化部署
    动态创建IIS站点
    网站架构设计(草稿)
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2594481.html
Copyright © 2011-2022 走看看