zoukankan      html  css  js  c++  java
  • 「SPOJ TTM 」To the moon「标记永久化」

    题意

    概括为主席树区间加区间询问

    题解

    记录一下标记永久化的方法。每个点存addsum两个标记,表示这个区间整个加多少,区间和是多少(这个区间和不包括祖先结点区间加)

    然后区间加的时候,给路上每结点的sum更新,然后到达完整区间后更新add。询问的时候把路径上所有结点(不包括自己)的add加起来乘以区间长度,再加上sum

    大概思想就是:区间内的加法用sum维护,区间外的加法询问的时候再考虑贡献

    #include <algorithm>
    #include <cstdio>
    using namespace std;
    
    typedef long long ll;
    
    const int N = 1e5 + 10;
    
    int n, m, a[N];
    int T[N], id, L[N << 6], R[N << 6];
    ll s[N << 6], add[N << 6];
    
    void build(int &rt, int l, int r) {
    	rt = ++ id;
    	if(l < r) {
    		int mid = (l + r) >> 1;
    		build(L[rt], l, mid);
    		build(R[rt], mid + 1, r);
    		s[rt] = s[L[rt]] + s[R[rt]];
    	} else s[rt] = a[l];
    }
    
    void update(int &rt, int pre, int l, int r, int ql, int qr, int x) {
    	rt = ++ id; L[rt] = L[pre]; R[rt] = R[pre];
    	s[rt] = s[pre] + (qr - ql + 1) * x; add[rt] = add[pre];
    	if(ql == l && r == qr) { add[rt] += x; return ; }
    	int mid = (l + r) >> 1;
    	if(qr <= mid) update(L[rt], L[pre], l, mid, ql, qr, x);
    	else if(ql > mid) update(R[rt], R[pre], mid + 1, r, ql, qr, x);
    	else {
    		update(L[rt], L[pre], l, mid, ql, mid, x);
    		update(R[rt], R[pre], mid + 1, r, mid + 1, qr, x);
    	}
    }
    
    ll query(int rt, int l, int r, int ql, int qr, ll sum = 0) {
    	if(ql == l && qr == r) return sum * (r - l + 1) + s[rt];
    	sum += add[rt];
    	int mid = (l + r) >> 1;
    	if(qr <= mid) return query(L[rt], l, mid, ql, qr, sum);
    	if(ql > mid) return query(R[rt], mid + 1, r, ql, qr, sum);
    	return query(L[rt], l, mid, ql, mid, sum) + query(R[rt], mid + 1, r, mid + 1, qr, sum);
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i ++)
    		scanf("%d", a + i);
    	static char op[5];
    	int tnow = 0; build(T[0], 1, n);
    	for(int l, r, d, i = 1; i <= m; i ++) {
    		scanf("%s", op);
    		if(* op == 'C') {
    			scanf("%d%d%d", &l, &r, &d);
    			update(T[tnow + 1], T[tnow], 1, n, l, r, d);
    			tnow ++;
    		}
    		if(* op == 'Q') {
    			scanf("%d%d", &l, &r);
    			printf("%lld
    ", query(T[tnow], 1, n, l, r));
    		}
    		if(* op == 'H') {
    			scanf("%d%d%d", &l, &r, &d);
    			printf("%lld
    ", query(T[d], 1, n, l, r));
    		}
    		if(* op == 'B') {
    			scanf("%d", &tnow);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Windows 系统共享文件扫描
    工业以太网EtherNet/IP协议安全分析整理
    说说搜索,你觉得自己的信息有多安全
    java网络编程
    攻击WordPress和其他程序
    ZenMap扫描笔记
    WireShark Wifi认证数据包分析(论文idea)
    linux 基础知识(三)
    unity 3D 学习笔记
    WPA-PSK无线网络密码破解原理
  • 原文地址:https://www.cnblogs.com/hongzy/p/11307145.html
Copyright © 2011-2022 走看看