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;
    }
    

      

  • 相关阅读:
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    206. Reverse Linked List
    205. Isomorphic Strings
    204. Count Primes
    203. Remove Linked List Elements
    201. Bitwise AND of Numbers Range
    199. Binary Tree Right Side View
    ArcGIS API for JavaScript 4.2学习笔记[8] 2D与3D视图同步
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8467873.html
Copyright © 2011-2022 走看看