• CodeVS 4927-线段树练习5


    题目&之前写过的题解

    题解

      这是我第二次写这道题了,也是我转语言之后写的第一次。

      首先要明确一点,不让一个节点同时拥有两个懒标记(delta,set),并且set的优先级比delta大,接着就好办了。

      于是你会发现,每个子程序的第一句话都是下传set标记。每次下传都要将该点的sum/max/min值计算一遍。

    代码:

    #include<cmath>
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define INF 10000000
    #define ll long long
    using namespace std;
    
    ll n,m,x,y,z;
    char ch[5];
    struct poi{int l,r;ll sum,delta,set,max,min;bool bn;} a[800010];
    
    ll calcsum(int x) {return a[x].bn? a[x].set*(a[x].r-a[x].l+1):a[x].sum+a[x].delta*(a[x].r-a[x].l+1);}
    ll calcmax(int x) {return a[x].bn? a[x].set:a[x].max+a[x].delta;}
    ll calcmin(int x) {return a[x].bn? a[x].set:a[x].min+a[x].delta;}
    void calc(int x)
    {
    	a[x].sum=calcsum(x<<1)+calcsum(x<<1|1);
    	a[x].max=max(calcmax(x<<1),calcmax(x<<1|1));
    	a[x].min=min(calcmin(x<<1),calcmin(x<<1|1));
    }
    
    void pushdownset(int x)
    {
    	a[x<<1].bn=a[x<<1|1].bn=1;a[x<<1].set=a[x<<1|1].set=a[x].set;a[x<<1].delta=a[x<<1|1].delta=0;
    	a[x].sum=calcsum(x);a[x].max=calcmax(x);a[x].min=calcmin(x);a[x].bn=0;
    }
    void pushdowndelta(int x)
    {
    	if (a[x<<1].bn) pushdownset(x<<1);if (a[x<<1|1].bn) pushdownset(x<<1|1);
    	a[x<<1].delta+=a[x].delta;a[x<<1|1].delta+=a[x].delta;
    	a[x].sum=calcsum(x);a[x].max=calcmax(x);a[x].min=calcmin(x);a[x].delta=0;
    }
    
    void build(int x,int l,int r)
    {
    	a[x].l=l; a[x].r=r;
    	if (l==r) {scanf("%lld",&a[x].sum); a[x].max=a[x].min=a[x].sum; return;}
    	build(x<<1,l,(l+r)>>1); build(x<<1|1,((l+r)>>1)+1,r);
    	calc(x);
    }
    
    void delta(int x,int l,int r,ll del)
    {
    	if (a[x].bn) pushdownset(x);
    	if (a[x].l>=l && a[x].r<=r) {a[x].delta+=del; return;}
    	if (a[x].delta) pushdowndelta(x);
    	if (l<=(a[x].l+a[x].r)>>1) delta(x<<1,l,r,del);
    	if (r>(a[x].l+a[x].r)>>1) delta(x<<1|1,l,r,del);
    	calc(x);
    }
    
    void set(int x,int l,int r,ll s)
    {
    	if (a[x].bn) pushdownset(x);
    	if (a[x].l>=l && a[x].r<=r) {a[x].bn=1; a[x].set=s; a[x].delta=0; return;}
    	if (a[x].delta) pushdowndelta(x);
    	if (l<=(a[x].l+a[x].r)>>1) set(x<<1,l,r,s);
    	if (r>(a[x].l+a[x].r)>>1) set(x<<1|1,l,r,s);
    	calc(x);
    }
    
    ll querysum(int x,int l,int r)
    {
    	ll ret=0;
    	if (a[x].bn) pushdownset(x);
    	if (a[x].l>=l && a[x].r<=r) return calcsum(x);
    	if (a[x].delta) pushdowndelta(x);
    	if (l<=(a[x].l+a[x].r)>>1) ret+=querysum(x<<1,l,r);
    	if (r>(a[x].l+a[x].r)>>1) ret+=querysum(x<<1|1,l,r);
    	return ret;
    }
    
    ll querymax(int x,int l,int r)
    {
    	ll ret=-INF;
    	if (a[x].bn) pushdownset(x);
    	if (a[x].l>=l && a[x].r<=r) return calcmax(x);
    	if (a[x].delta) pushdowndelta(x);
    	if (l<=(a[x].l+a[x].r)>>1) ret=max(ret,querymax(x<<1,l,r));
    	if (r>(a[x].l+a[x].r)>>1) ret=max(ret,querymax(x<<1|1,l,r));
    	return ret;
    }
    
    ll querymin(int x,int l,int r)
    {
    	ll ret=INF;
    	if (a[x].bn) pushdownset(x);
    	if (a[x].l>=l && a[x].r<=r) return calcmin(x);
    	if (a[x].delta) pushdowndelta(x);
    	if (l<=(a[x].l+a[x].r)>>1) ret=min(ret,querymin(x<<1,l,r));
    	if (r>(a[x].l+a[x].r)>>1) ret=min(ret,querymin(x<<1|1,l,r));
    	return ret;
    }
    
    main()
    {
    	scanf("%lld%lld",&n,&m);
        build(1,1,n);
        for (int i=1; i<=m; i++)
        {
            scanf("%s",ch);
            if (ch[0]=='a') {scanf("%lld%lld%lld",&x,&y,&z); delta(1,x,y,z);}
            if (ch[1]=='e') {scanf("%lld%lld%lld",&x,&y,&z); set(1,x,y,z);}
            if (ch[1]=='u') {scanf("%lld%lld",&x,&y); printf("%lld
    ",querysum(1,x,y));}
            if (ch[1]=='a') {scanf("%lld%lld",&x,&y); printf("%lld
    ",querymax(1,x,y));}
            if (ch[1]=='i') {scanf("%lld%lld",&x,&y); printf("%lld
    ",querymin(1,x,y));}
        }
        return 0;
    }
  • 相关阅读:
    java通过dom读写xml文件
    SWT
    Eclipse RCP学习资料
    Integration Guide
    一个Linux命令,黑客帝国
    GET和POST两种基本请求方法的区别
    贫血模式-AnemicDomainModel
    Synchronized锁在Spring事务管理下,为啥还线程不安全?
    redis 集群配置、启动
    redis cluster集群
  • 原文地址:https://www.cnblogs.com/HAdolf-HQY/p/7499830.html
Copyright © 2020-2023  润新知