• LCIS线段树(区间更新)


       首先线段树每一个节点包含:[b,e],lmax,rmax,max;其中lmax表示从左端点开始连续的最长的增序列长度,rmax表示从e端点开始向左连续的最长下降序列长度,max表示当前区间的连续递增的最长序列长度。对单个节点插入时的信息维护如下:

       (1) if 左儿子的右端点的值<右儿子的左端点的值

             lmax=左儿子区间长度==左儿子的lmax?左儿子区间长度+右儿子的lmax:左儿子的lmax.

             rmax=右儿子区间长度==右儿子的rmax?右儿子区间长度+左儿子的rmax:右儿子的rmax.

             max=MAX(lmax,rmax,左儿子的rmax+右儿子的lmax);

      (2)否则

            lmax=左儿子的lmax;

            rmax=右儿子的rmax;

            max=MAX(左儿子的max,右儿子的max);

    查寻操作如下:

          if 当前节点区间==查询区间

                  返回当前节点的max

          否则

                 返回 MAX(左区间,右区间,跨越边界的长度)

    //------------------------------------------------------------------
    //---线段树区间更新
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAXN = 1000000;
    struct Tnode{
    	int b, e;
    	int lmax;
    	int rmax;
    	int max;
    	int len(){ return e - b + 1; }
    };
    Tnode tree[4*MAXN];
    int p[MAXN];
    int n, m;
    int max(int a, int b, int c){
    	return max(max(a, b), c);
    }
    void Build(int v, int l, int r){
    	tree[v].b = l, tree[v].e = r;
    	tree[v].lmax = tree[v].rmax = tree[v].max = 0;
    	if (l < r){
    		int mid = (l + r) >> 1;
    		Build(2 * v + 1, l, mid);
    		Build(2 * v + 2, mid + 1, r);
    	}
    }
    void Insert(int v, int k, int val){
    	if (tree[v].b == tree[v].e){
    		//找到叶节点插入 
    		p[k] = val;
    		tree[v].lmax = tree[v].rmax = tree[v].max = 1;
    		return;
    	}
    	int mid = (tree[v].b + tree[v].e) >> 1;
    	if (k <= mid)
    		Insert(2 * v + 1, k, val);
    	else
    		Insert(2 * v + 2, k, val);
    	//接下来更新
    	if (p[mid] < p[mid + 1]){
    		if (tree[2 * v + 1].lmax == tree[2 * v + 1].len())
    			tree[v].lmax = tree[2 * v + 1].len() + tree[2 * v + 2].lmax;
    		else
    			tree[v].lmax = tree[2*v+1].lmax;
    
    		if (tree[2 * v + 2].rmax == tree[2 * v + 2].len())
    			tree[v].rmax = tree[2 * v + 2].len() + tree[2 * v + 1].rmax;
    		else
    			tree[v].rmax = tree[2*v+2].rmax;
    		tree[v].max = max(tree[2 * v + 1].max, tree[2 * v + 2].max,tree[2 * v + 1].rmax + tree[2 * v + 2].lmax);
    	}
    	else{
    		tree[v].lmax = tree[2*v+1].lmax;
    		tree[v].rmax = tree[2 * v + 2].rmax;
    		tree[v].max = max(tree[2 * v + 1].max,tree[2 * v + 2].max);
    	}
    }
    int Qurrey(int v,int l, int r){
    	if (l == tree[v].b&&r == tree[v].e)
    		return tree[v].max;
    	int mid = (tree[v].b + tree[v].e) >> 1;
    	if (r <= mid)
    		return Qurrey(2 * v + 1, l, r);
    	else if (l > mid)
    		return Qurrey(2 * v + 2, l, r);
    	else{
    		if (p[mid] < p[mid + 1]){
    			int left = max(mid + 1 - tree[2 * v + 1].rmax, l);
    			int right = min(r, mid + tree[2 * v + 2].lmax);
    			return max(Qurrey(2 * v + 1, l, mid), Qurrey(2 * v + 2, mid + 1, r), right-left+1);
    		}
    		else
    			return  max(Qurrey(2 * v + 1, l, mid), Qurrey(2 * v + 2, mid + 1, r));
    	} 
    }
    int main(){
    	int i, T,a,b;
    	char s;
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d%d", &n, &m);
    		memset(p, 0, sizeof(p));
    		Build(0, 0, n - 1);
    		for (i = 0; i < n; i++){
    			scanf("%d", &p[i]);
    			Insert(0, i, p[i]);
    		}
    		while (m--){
    			cin >> s;
    			scanf("%d%d",&a, &b);
    			if (s == 'U')
    				Insert(0, a, b);
    			else
    				printf("%d
    ", Qurrey(0, a, b));
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    云通信
    PullToRefreshGridView上拉刷新,下拉加载
    数据库开源框架GreenDao的使用解析
    RxJava2.0的使用详解
    ButterKnife的使用详解
    Jquery设置完颜色后hover不生效的解决办法
    jquery使用css函数设置背景色无效解决办法
    SpringBoot如何返回页面
    如何创建一个SpringBoot多模块项目
    连接mysql报错java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized...解决方法
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5764334.html
Copyright © 2020-2023  润新知