• @uoj



    @description@

    Picks博士观察完金星凌日后,设计了一个复杂的电阻器。为了简化题目,题目中的常数与现实世界有所不同。

    这个电阻器内有编号为 1∼n 的 n 个独立水箱,水箱呈圆柱形,底面积为 1 (m^2),每个水箱在顶部和底部各有一个阀门,可以让水以 1 (m^3/s) 的流量通过,每个水箱的上阀门接水龙头,可以无限供应水,下阀门不接东西,可以让水流出。水箱顶部和底部都有一个接口,水的电阻率为 1 Ω⋅m。

    水箱的高度足够高,有一个导电浮标浮在水面上,通过导线与水箱顶的接口相连。一开始时第 i 个水箱中有 (a_i) (m^3) 的水。

    Picks博士接下来就需要对这个复杂的电阻器进行调试。他会进行以下五种操作。

    1、打开编号在 [l,r] 中的所有水箱的上方阀门 x 秒,然后关上它们的上方阀门。
    2、打开编号在 [l,r] 中的所有水箱的下方阀门 x 秒,然后关上它们的下方阀门。
    3、将编号在 [l,r] 中的所有水箱的下方阀门与大海通过连通器以一定方式相连,使得这些水箱中都恰拥有 (x) (m^3) 的水,然后关上它们的下方阀门,撤去连通器。
    4、在第 y 个水箱的上下方接口处接上一个电动势为 1 V 的电源,电源没有内阻,Picks博士会测量出通过电源的电流大小,之后撤去该电源。
    5、由于水浸泡过的地方会留下明显的水渍而没有被水浸泡过的地方不会有,Picks博士可以据此测量出此时第 y 个水箱的水渍高度,以推断曾经最多有多少水,节约他的建造成本。

    现在,他请你来帮他做预实验,你能告诉他每次测量得到的电流大小以及测量得到的最多的水量是多少吗?

    原题传送门。

    @solution@

    来翻译一遍题目的操作:

    t = 1 : [li, ri] 中的所有 aj 变成 aj + xi。
    t = 2 : [li, ri] 中的所有 aj 变成 max(aj - xi, 0)。
    t = 3 : [li, ri] 中的所有 aj 变成 xi。
    t = 4 : 询问 ayi。
    t = 5 : 询问 ayi 在历史上的最大值。

    可以发现 1 操作也可写成 max(aj + xi, 0),3 操作也可写成 max(-∞, xi),这样所有修改的形式就统一成 max(x + a, b) 了。

    两个修改标记的复合为 max(max(x + a1, b1) + a2, b2) = max(x + max(a1, a2), max(b1 + a2, b2))。
    注意到这个复合运算满足结合律(但不满足交换律),所以可以用线段树维护。

    如何维护历史最大值?我们尝试对两个修改标记取 max:max(max(x + a1, b1), max(x + a2, b2)) = max(x + max(a1, a2), max(b1, b2)),发现是可行的。
    于是我们再在每个结点处维护一个历史最大未下传标记即可。

    @accepted code@

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    typedef long long ll;
    
    const int MAXN = 500000;
    const ll INF = 1E16;
    
    ll add(ll x, ll y) {
    	return x + y > INF ? INF : (x + y < -INF ? -INF : x + y);
    }
    struct tag{
    	ll a, b; tag() {}
    	tag(ll _a, ll _b) : a(_a), b(_b) {}
    	friend tag add(tag a, tag b) {
    		return tag(add(a.a, b.a), max(add(a.b, b.a), b.b));
    	}// max(max(x + a.a, a.b) + b.a, b.b)
    	friend tag max(tag a, tag b) {
    		return tag(max(a.a, b.a), max(a.b, b.b));
    	}// max(max(x + a.a, a.b), max(x + b.a, b.b))
    };
    
    int a[MAXN + 5];
    struct segtree{
    	#define lch (x << 1)
    	#define rch (x << 1 | 1)
    	
    	int le[4*MAXN + 5], ri[4*MAXN + 5];
    	tag tg[4*MAXN + 5], mt[4*MAXN + 5];
    	void build(int x, int l, int r) {
    		le[x] = l, ri[x] = r, tg[x] = tag(0, 0);
    		if( l == r ) {
    			tg[x] = mt[x] = tag(a[l], 0);
    			return ;
    		}
    		int m = (l + r) >> 1;
    		build(lch, l, m), build(rch, m + 1, r);
    	}
    	void maintain(int x, tag nwt, tag mxt) {
    		mt[x] = max(mt[x], add(tg[x], mxt));
    		tg[x] = add(tg[x], nwt);
    	}
    	void pushdown(int x) {
    		if( tg[x].a || tg[x].b ) {
    			maintain(lch, tg[x], mt[x]);
    			maintain(rch, tg[x], mt[x]);
    			tg[x] = mt[x] = tag(0, 0);
    		}
    	}
    	void modify(int x, int l, int r, tag t) {
    		if( l > ri[x] || r < le[x] )
    			return ;
    		if( l <= le[x] && ri[x] <= r ) {
    			maintain(x, t, t);
    			return ;
    		}
    		pushdown(x);
    		modify(lch, l, r, t), modify(rch, l, r, t);
    	}
    	tag query(int x, int p, int type) {
    		if( le[x] == ri[x] ) return (type == 4 ? tg[x] : mt[x]);
    		int m = (le[x] + ri[x]) >> 1;
    		pushdown(x);
    		if( p <= m ) return query(lch, p, type);
    		else return query(rch, p, type);
    	}
    }T;
    
    int main() {
    	int n, m; scanf("%d%d", &n, &m);
    	for(int i=1;i<=n;i++) scanf("%d", &a[i]);
    	T.build(1, 1, n);
    	for(int i=1;i<=m;i++) {
    		int t; scanf("%d", &t);
    		if( t <= 3 ) {
    			int l, r, k; tag p; scanf("%d%d%d", &l, &r, &k);
    			if( t == 1 ) p = tag(k, 0);
    			if( t == 2 ) p = tag(-k, 0);
    			if( t == 3 ) p = tag(-INF, k);
    			T.modify(1, l, r, p);
    		}
    		else {
    			int y; scanf("%d", &y);
    			tag p = T.query(1, y, t);
    			printf("%lld
    ", max(p.a, p.b));
    		}
    	}
    }
    
    /*
    t = 1 : [li, ri] + x
    t = 2 : max([li, ri] - x, 0)
    t = 3 : [li, ri] = x
    t = 4 : query ax
    t = 5 : query history max{ax}
    */
    

    @details@

    听说是吉如一线段树(segment tree beats)的一部分来着,不过不是很清楚。

  • 相关阅读:
    APP-SERVICE-SDK:setStorageSync:fail;at page/near/pages/shops/shops page lifeCycleMethod onUnload function
    css 别人找的css特效
    项目笔记2
    Win7如何删除需要管理员权限才能删除的文件夹
    Win7下C:UsersCortana以账户名称命名的系统文件夹用户名的修改
    Win10下C:UsersJohn以账户名称命名的系统文件夹用户名的修改
    windows10企业版怎么关闭自动更新
    给MySQL_5.7 配置环境变量
    用PE安装操作系统时:无法创建新的系统分区 也无法定位现有系统分区 的解决办法
    电脑内存和磁盘空间有什么区别与联系
  • 原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/12421203.html
Copyright © 2020-2023  润新知