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;
    }
    
  • 相关阅读:
    结巴分词 0.14 版发布,Python 中文分词库
    Lazarus 1.0.2 发布,Pascal 集成开发环境
    Android全屏 去除标题栏和状态栏
    服务器日志现 Android 4.2 传将添多项新特性
    Percona XtraBackup 2.0.3 发布
    长平狐 Android 强制设置横屏或竖屏 设置全屏
    NetBeans 7.3 Beta 发布,全新的 HTML5 支持
    CppDepend现在已经支持Linux
    GromJS 1.7.18 发布,服务器端的 JavaScript
    Apache OpenWebBeans 1.1.6 发布
  • 原文地址:https://www.cnblogs.com/Nicoppa/p/11424092.html
Copyright © 2011-2022 走看看