[题解]codeforces444c DZY Loves Colors

来源:互联网 发布:室内定位 指纹算法 编辑:程序博客网 时间:2024/06/06 09:43

题目:戳这里
题目大意:
给定一个序列,初始Ai=i,区间赋值操作,定义i位置的元素的贡献为该位置元素每次改变的值的绝对值之和,多次询问区间内的元素贡献之和。

Solution

线段树,区间相同就统一修改,区间不同就暴力递归。注意本题的标记,每次加上新的标记时都会对答案产生贡献,不能只在覆盖标记上修改,还应该记录一下当前区间对答案的贡献作为标记下传。

#include<cstdio>#include<algorithm>using namespace std;template<typename T>inline void read(T &x){    T f=1;char ch=getchar();    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;    for(x=0;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';    x*=f;}typedef long long LL;LL fabs(LL x){    return x>0?x:-x;}const int maxn=100010;struct Seg_Tree{    #define lc x<<1    #define rc x<<1|1    int L[maxn<<2],R[maxn<<2];    int same[maxn<<2],is[maxn<<2];    LL sum[maxn<<2],add[maxn<<2];    void Build(int x,int l,int r){        same[x]=-1;is[x]=sum[x]=add[x]=0;        if((L[x]=l)==(R[x]=r))return is[x]=l,void();        int mid=(l+r)>>1;        Build(lc,l,mid);Build(rc,mid+1,r);    }    void update(int x){        sum[x]=sum[lc]+sum[rc];        if(is[lc]&&is[rc]&&is[lc]==is[rc])is[x]=is[lc];        else is[x]=0;    }    void pushsame(int x,int c){        same[x]=is[x]=c;    }    void pushadd(int x,LL c){        add[x]+=c;sum[x]+=(LL)(R[x]-L[x]+1)*c;    }    void pushdown(int x){        if(same[x]!=-1){            pushsame(lc,same[x]);            pushsame(rc,same[x]);            same[x]=-1;        }        if(add[x]){            pushadd(lc,add[x]);            pushadd(rc,add[x]);            add[x]=0;        }    }    void Modify(int x,int l,int r,int c){        if(L[x]>=l&&R[x]<=r&&is[x]){            LL temp=fabs(c-is[x]);            pushadd(x,temp);pushsame(x,c);            return;        }        pushdown(x);        int mid=(L[x]+R[x])>>1;        if(l<=mid)Modify(lc,l,r,c);        if(r>mid)Modify(rc,l,r,c);        update(x);    }    LL Query(int x,int l,int r){        if(L[x]>=l&&R[x]<=r)return sum[x];        int mid=(L[x]+R[x])>>1;LL ans=0;        pushdown(x);        if(l<=mid)ans+=Query(lc,l,r);        if(r>mid)ans+=Query(rc,l,r);        return ans;    }}tree;int n,m;int main(){    read(n);read(m);    tree.Build(1,1,n);    while(m--){        int opt,l,r,x;        read(opt);read(l);read(r);        if(opt==1){            read(x);            tree.Modify(1,l,r,x);        }        else if(opt==2)printf("%lld\n",tree.Query(1,l,r));    }    return 0;}
原创粉丝点击