• UOJ#288:基础数据结构练习题


    题面

    UOJ

    Sol

    玄学,不会势能分析
    所以
    维护区间最大最小值
    把开根变成区间减法
    如果最大值开根后的变化量和最小值的相等,就直接打个减法(lazy)

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    # define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
    using namespace std;
    typedef long long ll;
    const int _(1e5 + 5);
    
    IL int Input(){
    	RG int x = 0, z = 1; RG char c = getchar();
    	for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    	for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    	return x * z;
    }
    
    int n, m;
    struct Segment{
    	ll mx, mn, tag, sum;
    } T[_ << 2];
    
    IL void Build(RG int x, RG int l, RG int r){
    	if(l == r){
    		T[x].mn = T[x].mx = T[x].sum = Input();
    		return;
    	}
    	RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1;
    	Build(ls, l, mid), Build(rs, mid + 1, r);
    	T[x].mn = min(T[ls].mn, T[rs].mn);
    	T[x].mx = max(T[ls].mx, T[rs].mx);
    	T[x].sum = T[ls].sum + T[rs].sum;
    }
    
    IL void Adjust(RG int x, RG ll v, RG int l, RG int r){
    	T[x].tag += v, T[x].mx += v, T[x].mn += v, T[x].sum += 1LL * (r - l + 1) * v;
    }
    
    IL void Pushdown(RG int x, RG int l, RG int mid, RG int r){
    	if(T[x].tag == 0) return;
    	Adjust(x << 1, T[x].tag, l, mid);
    	Adjust(x << 1 | 1, T[x].tag, mid + 1, r);
    	T[x].tag = 0;
    }
    
    IL void Modify2(RG int x, RG int l, RG int r, RG int L, RG int R, RG ll v){
    	if(L <= l && R >= r){
    		Adjust(x, v, l, r);
    		return;
    	}
    	RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1;
    	Pushdown(x, l, mid, r);
    	if(L <= mid) Modify2(ls, l, mid, L, R, v);
    	if(R > mid) Modify2(rs, mid + 1, r, L, R, v);
    	T[x].mn = min(T[ls].mn, T[rs].mn);
    	T[x].mx = max(T[ls].mx, T[rs].mx);
    	T[x].sum = T[ls].sum + T[rs].sum;
    }
    
    IL void Modify1(RG int x, RG int l, RG int r, RG int L, RG int R){
    	RG ll v1 = sqrt(T[x].mn), v2 = sqrt(T[x].mx);
    	v1 -= T[x].mn, v2 -= T[x].mx;
    	if(v1 == v2){
    		Modify2(x, l, r, L, R, v1);
    		return;
    	}
    	RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1;
    	Pushdown(x, l, mid, r);
    	if(L <= mid) Modify1(ls, l, mid, L, R);
    	if(R > mid) Modify1(rs, mid + 1, r, L, R);
    	T[x].mn = min(T[ls].mn, T[rs].mn);
    	T[x].mx = max(T[ls].mx, T[rs].mx);
    	T[x].sum = T[ls].sum + T[rs].sum;
    }
    
    IL ll Query(RG int x, RG int l, RG int r, RG int L, RG int R){
    	if(L <= l && R >= r) return T[x].sum;
    	RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1;
    	RG ll ans = 0;
    	Pushdown(x, l, mid, r);
    	if(L <= mid) ans = Query(ls, l, mid, L, R);
    	if(R > mid) ans += Query(rs, mid + 1, r, L, R);
    	T[x].mn = min(T[ls].mn, T[rs].mn);
    	T[x].mx = max(T[ls].mx, T[rs].mx);
    	T[x].sum = T[ls].sum + T[rs].sum;
    	return ans;
    }
    
    int main(RG int argc, RG char *argv[]){
    	n = Input(), m = Input(), Build(1, 1, n);
    	while(m--){
    		RG int op = Input(), l = Input(), r = Input(), v;
    		if(op == 1) v = Input(), Modify2(1, 1, n, l, r, v);
    		else if(op == 2) Modify1(1, 1, n, l, r);
    		else printf("%lld
    ", Query(1, 1, n, l, r));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    PrintWriter、PrintStream的苦头 缓冲区问题
    BufferedImage与byte[]互转
    求两个日期的间隔天数
    Timer和TimerTask详解
    Java连接Access数据库
    根据value字段对map进行排序
    java collections读书笔记(3)Arrays
    java collections读书笔记(4) stack
    运行时异常与一般异常有何异同?(转)
    java collections读书笔记(7) bitset
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8582848.html
Copyright © 2020-2023  润新知