• codevs 4927 线段树练习5 题解


    一、题目:

    codevs原题

    二、思路:

    这将是我NOIP2018前的最后一篇题解,从现在到NOIP我将进入总复习阶段。祝NOIP rp++。

    那么这道题显然会有两个标记,一个add标记,一个set标记。那么怎样才能使这两个标记互不影响呢?

    我们规定一个顺序,当set标记打过来时,我们首先将add标记清零,再打set标记。

    改了改代码风格,具体请见博客置顶文章。

    三、代码:

    /*
     * @Author: 岸芷汀兰
     * @Date: 2018-10-15 22:11:37
     * @LastEditors: 岸芷汀兰
     * @LastEditTime: 2018-10-15 23:13:52
     * @Description: 4927 of codevs
     */
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>    
    #include<algorithm>    
    #include<string>
    
    #define LL long long
    #define mem(s,v) memset(s,v,sizeof(s))
    
    using namespace std;
    template<class Type>
    inline Type read(void) {
    	Type x = 0, f = 1; char ch = getchar();
    	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    	while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    	return f * x;
    }
    
    const int maxn = 100005;
    
    int n, m;
    
    LL a[maxn];
    
    struct Segment_Tree {
    #define lson (o << 1)
    #define rson (o << 1 | 1)
    	LL set[maxn << 2], add[maxn << 2], sum[maxn << 2], maxv[maxn << 2], minv[maxn << 2], len[maxn << 2];
    	inline void pushup(int o) {
    		sum[o] = sum[lson] + sum[rson];
    		maxv[o] = max(maxv[lson], maxv[rson]);
    		minv[o] = min(minv[lson], minv[rson]);
    	}
    	inline void build(int o, int l, int r) {
    		len[o] = r - l + 1;
    		add[o] = sum[o] = maxv[o] = minv[o] = 0;
    		set[o] = -1;
    		if (l == r) { sum[o] = a[l]; maxv[o] = a[l]; minv[o] = a[l]; return; }
    		int mid = (l + r) >> 1;
    		build(lson, l, mid);
    		build(rson, mid + 1, r);
    		pushup(o);
    	}
    	inline void Add(int o,int v){
    		add[o]+=v;
    		sum[o]+=len[o]*v;
    		minv[o]+=v;maxv[o]+=v;
    		return;
    	}
    	inline void Set(int o,int v){
    		set[o]=v;add[o]=0;
    		sum[o]=len[o]*v;
    		maxv[o]=minv[o]=v;
    		return;
    	}
    	inline void pushdown(int o){
    		if(set[o]!=-1){
    			Set(lson,set[o]);Set(rson,set[o]);
    			set[o]=-1;
    		}
    		if(add[o]){
    			Add(lson,add[o]);Add(rson,add[o]);
    			add[o]=0;
    		}
    		return;
    	}
    	inline void Update(int o,int l,int r,int ql,int qr,int k,LL v){
    		if(ql<=l&&r<=qr){
    			if(k==1){//add
    				Add(o,v);return;
    			}
    			else{//set
    				Set(o,v);return;
    			}
    		}
    		pushdown(o);
    		int mid=(l+r)>>1;
    		if(ql<=mid)Update(lson,l,mid,ql,qr,k,v);
    		if(qr>mid)Update(rson,mid+1,r,ql,qr,k,v);
    		pushup(o);
    	}
    	inline LL query(int o,int l,int r,int ql,int qr,int k){
    		if(ql<=l&&r<=qr){
    			switch(k){
    				case 1://sum
    					return sum[o];
    				case 2://max
    					return maxv[o];
    				case 3://min
    					return minv[o];
    			}
    		}
    		pushdown(o);
    		int mid=(l+r)>>1;LL ans=0;
    		switch(k){
    			case 1://sum
    				if(ql<=mid)ans+=query(lson,l,mid,ql,qr,k);
    				if(qr>mid)ans+=query(rson,mid+1,r,ql,qr,k);
    				return ans;
    			case 2://max
    				ans=-0x3f3f3f3f3f3f3f3f;
    				if(ql<=mid)ans=max(ans,query(lson,l,mid,ql,qr,k));
    				if(qr>mid)ans=max(ans,query(rson,mid+1,r,ql,qr,k));
    				return ans;
    			case 3://min
    				ans=0x3f3f3f3f3f3f3f3f;
    				if(ql<=mid)ans=min(ans,query(lson,l,mid,ql,qr,k));
    				if(qr>mid)ans=min(ans,query(rson,mid+1,r,ql,qr,k));
    				return ans;
    		}
    	}
    }T;
    
    int main() {
    	n = read<int>(); m = read<int>();
    	for (register int i = 1; i <= n; ++i) {
    		a[i] = read<LL>();
    	}
    	T.build(1, 1, n);
    	for (register int i = 1; i <= m; ++i) {
    		string s; cin >> s;
    		if (s == "add") {
    			int l = read<int>(), r = read<int>(); LL c = read<LL>();
    			T.Update(1, 1, n, l, r, 1, c);
    		}
    		else if (s == "set") {
    			int l = read<int>(), r = read<int>(); LL c = read<LL>();
    			T.Update(1, 1, n, l, r, 2, c);
    		}
    		else if (s == "sum") {
    			int l = read<int>(), r = read<int>();
    			printf("%lld
    ", T.query(1, 1, n, l, r, 1));
    		}
    		else if (s == "max") {
    			int l = read<int>(), r = read<int>();
    			printf("%lld
    ", T.query(1, 1, n, l, r, 2));
    		}
    		else if (s == "min") {
    			int l = read<int>(), r = read<int>();
    			printf("%lld
    ", T.query(1, 1, n, l, r, 3));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    《《《Postman 的官网下转
    《《《Springboot 配置 application.yml 连接MySQL数据库
    《《《MyBatis-Plus完成可用项目(通过测试可以连接数据库并返回数据(可以当作开发模板使用))
    《《《spring boot配置文件application.yml出现的异常信息:(java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml')
    《《《转载 Intellij IDEA 导入Maven项目
    start.spring.io访问不了,导致springboot项目创建不起来(Initialization failed for 'https://start.spring.io' Please check URL, network and proxy settings. Error mes...)
    《《《MyBatis-Plus入门 视频学习笔记
    在pom.xml中查看引入关系图
    《《《如何建立局域网共享文件夹(怎样通过IP地址共享文件夹(同一个局域网下))
    JS跨域问题及其解决办法
  • 原文地址:https://www.cnblogs.com/little-aztl/p/9803517.html
Copyright © 2020-2023  润新知