CodeForces 444C 线段树

想分块想了很久一点思路都没有,结果一看都是写的线段树= = 。。。完全忘记了还有线段树这种操作

题意:给一个数组,一种操作是改变l到r为c,还有一种操作是查询l到r的总和差

线段树记得+lazy标记

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 998244353
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;

const double g=10.0,eps=1e-7;
const int N=100000+10,maxn=sqrt(N)+100,inf=0x3f3f3f3f;

ll color[N<<2],lazy[N<<2],sum[N<<2];
bool same[N<<2];
void changecolor(ll c,ll x,int l,int r,int rt)//x是改变的差值,c是上一个颜色
{
    same[rt]=1;
    sum[rt]+=x*(r-l+1);
    color[rt]=c;
    lazy[rt]+=x;
}
void pushup(int rt)
{
    if(same[rt<<1]&&same[rt<<1|1]&&color[rt<<1]==color[rt<<1|1])
    {
        same[rt]=1;
        color[rt]=color[rt<<1];
    }
    else same[rt]=0;
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(int l,int r,int rt)
{
    if(lazy[rt])
    {
        int m=(l+r)>>1;
        changecolor(color[rt],lazy[rt],ls);
        changecolor(color[rt],lazy[rt],rs);
        lazy[rt]=0;
    }
}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        color[rt]=l;
        same[rt]=1;
        sum[rt]=0;
        return ;
    }
    int m=(l+r)>>1;
    build(ls);
    build(rs);
    pushup(rt);
}
void update(int l,int r,int rt,int L,int R,ll x)
{
    if(L<=l&&r<=R&&same[rt])
    {
        changecolor(x,abs(x-color[rt]),l,r,rt);
        return ;
    }
    pushdown(l,r,rt);
    int m=(l+r)>>1;
    if(L<=m)update(ls,L,R,x);
    if(m<R)update(rs,L,R,x);
    pushup(rt);
}
ll query(int l,int r,int rt,int L,int R)
{
    if(L<=l&&r<=R)return sum[rt];
    pushdown(l,r,rt);
    int m=(l+r)>>1;
    ll ans=0;
    if(L<=m)ans+=query(ls,L,R);
    if(m<R)ans+=query(rs,L,R);
    return ans;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    build(1,n,1);
    while(m--)
    {
        int x,y;
        ll z;
        scanf("%d",&x);
        if(x==1)
        {
            scanf("%d%d%lld",&x,&y,&z);
            update(1,n,1,x,y,z);
        }
        else
        {
            scanf("%d%d",&x,&y);
            printf("%lld
",query(1,n,1,x,y));
        }
    }
    return 0;
}
/********************

********************/
View Code