Codeforces 444C DZY Loves Colors

来源:互联网 发布:趣头条提现是骗局 知乎 编辑:程序博客网 时间:2024/04/30 17:06

题意:

开始有1~n种颜色在1~n的区间上,现在有两种操作:

1 a b c表示将a~b区间的颜色涂为c,区间内的每个点会累加上值|new颜色-old颜色|。

2 a b求出a~b区间内每个点的值的和。

思路:

线段树+lazy标志。这里设置三个变量sum表示所求值的和,col表示当前节点上的颜色,lazy表示累加的值。

#include<cstdio>#include<cmath>using namespace std;typedef __int64 LL;const int MAX=1e5+5;LL sum[MAX<<2];LL col[MAX<<2];LL lazy[MAX<<2];void PushUp(int rt){if(col[rt<<1]==col[rt<<1|1]) col[rt]=col[rt<<1];else col[rt]=0;sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void PushDown(int rt,int m){if(col[rt]){col[rt<<1]=col[rt<<1|1]=col[rt];lazy[rt<<1]+=lazy[rt],lazy[rt<<1|1]+=lazy[rt];sum[rt<<1]+=lazy[rt]*(LL)(m-(m>>1)),sum[rt<<1|1]+=lazy[rt]*(LL)(m>>1);col[rt]=lazy[rt]=0;}}void Build(int l,int r,int rt){if(l==r){sum[rt]=0;col[rt]=l;return;}int mid=(l+r)>>1;Build(l,mid,rt<<1);Build(mid+1,r,rt<<1|1);PushUp(rt);}void UpDate(int L,int R,int c,int l,int r,int rt){if(L<=l&&r<=R&&col[rt]){sum[rt]+=abs(col[rt]-c)*(LL)(r-l+1);lazy[rt]+=abs(col[rt]-c);col[rt]=c;return;}PushDown(rt,r-l+1);int mid=(l+r)>>1;if(L<=mid) UpDate(L,R,c,l,mid,rt<<1);if(mid<R) UpDate(L,R,c,mid+1,r,rt<<1|1);PushUp(rt);}LL Query(int L,int R,int l,int r,int rt){if(L<=l&&r<=R){return sum[rt];}PushDown(rt,r-l+1);LL res=0;int mid=(l+r)>>1;if(L<=mid) res+=Query(L,R,l,mid,rt<<1);if(mid<R) res+=Query(L,R,mid+1,r,rt<<1|1);return res;}int main(){int n,m,op,a,b,c;scanf("%d%d",&n,&m);Build(1,n,1);while(m--){scanf("%d",&op);if(op==1){scanf("%d%d%d",&a,&b,&c);UpDate(a,b,c,1,n,1);}else{scanf("%d%d",&a,&b);printf("%I64d\n",Query(a,b,1,n,1));}}return 0;}


0 0
原创粉丝点击