zoukankan      html  css  js  c++  java
  • 「线段树」你能回答这些问题吗

    给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:

    1、“1 x y”,查询区间 [x,y] 中的最大连续子段和,即 (max_{x≤l≤r≤y}Sigma_{i = l}^rA[i])

    2、“2 x y”,把 A[x] 改成 y。

    对于每个查询指令,输出一个整数表示答案。

    输入格式

    第一行两个整数N,M。

    第二行N个整数A[i]。

    接下来M行每行3个整数k,x,y,k=1表示查询(此时如果x>y,请交换x,y),k=2表示修改。

    输出格式

    对于每个查询指令输出一个整数表示答案。

    每个答案占一行。

    数据范围

    (N≤500000,M≤100000)

    输入样例:

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

    输出样例:

    2
    -1
    

    题目题解:

    一道线段树求区间最大子段和的题

    很简单..模板

    //#define fre yes
    
    #include <cstdio>
    #include <iostream>
    
    const int N = 500005;
    struct Node {
    	int l, r;
    	long long lsum, rsum, sum, mx;
    } tree[N << 2];
    
    long long ans = 0;
    
    void updown(int k) {
    	tree[k].sum = tree[k * 2].sum + tree[k * 2 + 1].sum;
    	tree[k].lsum = std::max(tree[k * 2].lsum, tree[k * 2].sum + tree[k * 2 + 1].lsum);
    	tree[k].rsum = std::max(tree[k * 2 + 1].rsum, tree[k * 2 + 1].sum + tree[k * 2].rsum);
    	tree[k].mx = std::max(tree[k * 2].mx, tree[k * 2 + 1].mx);
    	tree[k].mx = std::max(tree[k].mx, tree[k * 2].rsum + tree[k * 2 + 1].lsum);
    
    
    }
    
    void build(int k, int l, int r) {
    	tree[k].l = l; tree[k].r = r;
    	if(l == r) {
    		scanf("%lld", &tree[k].sum);
    		tree[k].lsum = tree[k].rsum = tree[k].mx = tree[k].sum;
    		return ;
    	}
    	
    	int mid = (l + r) >> 1;
    	build(k * 2, l, mid);
    	build(k * 2 + 1, mid + 1, r);
    	updown(k);
    }
    
    void change(int k, int x, int y) {
    	if(tree[k].l == tree[k].r) {
    		tree[k].lsum = tree[k].rsum = tree[k].mx = tree[k].sum = y;
    		return ;
    	}
    	
    	int mid = (tree[k].l + tree[k].r) >> 1;
    	if(mid >= x) change(k * 2, x, y);
    	else change(k * 2 + 1, x, y);
    	updown(k);
    }
    
    Node ask(int k, int l, int r) {
    	if(tree[k].l >= l && tree[k].r <= r) {
    		return tree[k];
    	}
    	
    	int mid = (tree[k].l + tree[k].r) >> 1;
    	if(r <= mid) return ask(k * 2, l, r);
    	if(l > mid) return ask(k * 2 + 1, l, r);
    	Node a, b, c;
    	a = ask(k * 2, l, mid);
    	b = ask(k * 2 + 1, mid + 1, r);
    	c.sum = a.sum + b.sum;
    	c.lsum = std::max(a.lsum, a.sum + b.lsum);
    	c.rsum = std::max(b.rsum, b.sum + a.rsum);
    	c.mx = std::max(a.rsum + b.lsum, std::max(a.mx, b.mx));
    	return c;
    }
    
    int main() {
    	static int n, m;
    	scanf("%d %d", &n, &m);
    	build(1, 1, n);
    	for (int i = 1; i <= m; i++) {
    		int x, y, z;
    		scanf("%d %d %d", &x, &y, &z);
    		if(x == 1) {
    			ans = 0;
    			if(y > z) std::swap(y, z);
    			Node w = ask(1, y, z);
    			printf("%lld
    ", w.mx);
    		}
    		
    		if(x == 2) {
    			change(1, y, z);
    		}
    	} return 0;
    }
    
  • 相关阅读:
    LINUX 系统性能检测工具vmstat
    ebs 初始化登陆
    oracle 以SYSDBA远程连接数据库
    ORACLE hint
    ORACLE CACHE BUFFER CHAINS原理
    oracle 当月日历的sql
    oracle to_char处理日期
    EBS 抓trace 文件
    oracle 执行计划的获取方法
    linux ln用法
  • 原文地址:https://www.cnblogs.com/Nicoppa/p/11424092.html
Copyright © 2011-2022 走看看