zoukankan      html  css  js  c++  java
  • Wannafly挑战赛10 D 小H的询问(线段树)

    题目链接  Problem D

    这个题类似 SPOJ GSS3

    做过那个题之后其实就可以秒掉这题了。

    考虑当前线段树维护的结点

    在那道题的基础上,这个题要多维护几个东西,大概就是左端点的奇偶性,右端点的奇偶性。

    以及当前结点代表的区间是否是一个有效的子序列。

    时间复杂度$O(nlogn)$

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define	ls		i << 1
    #define	rs		i << 1 | 1
    #define	mid		((l + r) >> 1)
    #define	lson		ls, l, mid
    #define	rson		rs, mid + 1, r
    
    
    typedef long long LL;
    
    const int N = 1e5 + 10;
    
    struct node{
    	LL c, lc, rc, ret;
    	int lo, ro, flag;
    } t[N << 2];
    
    int n, m;
    
    void pushup(int i){
    	t[i].c = t[ls].c + t[rs].c;
    	t[i].ret = max(t[ls].ret, t[rs].ret);
    	t[i].flag = 0;
    	t[i].lc = t[ls].lc;
    	t[i].rc = t[rs].rc;
    	t[i].lo = t[ls].lo;
    	t[i].ro = t[rs].ro;
    	
    	if (t[ls].ro ^ t[rs].lo){
    		t[i].ret = max(t[i].ret, t[ls].rc + t[rs].lc);
    		if (t[ls].flag) t[i].lc = max(t[i].lc, t[ls].c + t[rs].lc);
    		if (t[rs].flag) t[i].rc = max(t[i].rc, t[rs].c + t[ls].rc);
    		if (t[ls].flag && t[rs].flag) t[i].flag = 1;
    	}
    }	
    
    void build(int i, int l, int r){
    	if (l == r){
    		scanf("%lld", &t[i].ret);
    		t[i].c = t[i].lc = t[i].rc = t[i].ret;
    		t[i].lo = t[i].ro = (t[i].ret & 1);
    		t[i].flag = 1;
    		return;
    	}
    
    	build(lson);
    	build(rson);
    	pushup(i);
    }
    
    void update(int i, int l, int r, int x, LL val){
    	if (l == x && l == r){
    		t[i].ret = t[i].c = t[i].lc = t[i].rc = val;
    		t[i].lo = t[i].ro = (val & 1);
    		t[i].flag = 1;
    		return;
    	}
    
    	if (x <= mid) update(lson, x, val);
    	else update(rson, x, val);
    	pushup(i);
    }
    
    node query(int i, int l, int r, int L, int R){
    	if (L <= l && r <= R) return t[i];
    	
    	if (R <= mid) return query(lson, L, R);
    	if (L >  mid) return query(rson, L, R);
    
    	node ta = query(lson, L, mid);
    	node tb = query(rson, mid + 1, R);
    
    	node ans;
    	ans.c = ta.c + tb.c;
    	ans.ret = max(ta.ret, tb.ret);
    	ans.flag = 0;
    	ans.lc = ta.lc;
    	ans.rc = tb.rc;
    	ans.lo = ta.lo;
    	ans.ro = tb.ro;
    	if (ta.ro ^ tb.lo){
    		ans.ret = max(ans.ret, ta.rc + tb.lc);
    		if (ta.flag) ans.lc = max(ans.lc, ta.c + tb.lc);
    		if (tb.flag) ans.rc = max(ans.rc, tb.c + ta.rc);
    		if (ta.flag && tb.flag) ans.flag = 1;
    	}
    
    	return ans;
    }
    
    int main(){
    
    	scanf("%d%d", &n, &m);
    	build(1, 1, n);
    
    	while (m--){
    		int op;
    		scanf("%d", &op);
    		if (op == 0){
    			int x, y;
    			scanf("%d%d", &x, &y);
    			node ans = query(1, 1, n, x, y);
    			printf("%lld
    ", ans.ret);
    		}
    
    		else{
    			int x;
    			LL y;
    			scanf("%d%lld", &x, &y);
    			update(1, 1, n, x, y);
    		}
    	}
    
    	return 0;
    }
    

      

  • 相关阅读:
    Linux上Blogilo连接博客园账户
    字符串模式匹配KMP算法
    回溯法之n皇后问题
    回溯法之k着色问题
    动态规划之最短路径(Floyd算法)
    动态规划之最长公共子序列
    动态规划之矩阵链乘
    New home
    POJ 2478:Farey Sequence
    Codeforces Round #416 (Div. 2)
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8467873.html
Copyright © 2011-2022 走看看