设为首页 加入收藏

TOP

CodeForces 444C DZY Loves Colors
2015-07-20 18:07:15 来源: 作者: 【 】 浏览:3
Tags:CodeForces 444C DZY Loves Colors

题意:

一段区间a一开始是1、2、3、4……n这样的 每次1操作可以将[l,r]覆盖成x 同时得到abs(a[i]-x)的价值 2操作查询[l,r]的价值


思路:

线段树 又是一道加深线段树理解的题

操作2是简单的求和 线段树基本操作 难点在操作1

用cov表示该区间的值(如果为0说明是混合区间) 用val表示该区间的价值和

那么在更新时就不仅仅是找到 tree[i].l==l&&tree[i].r==r 就停止了 而是继续向下递归 直到一段区间的cov>0才结束

之所以这么做是因为要将x覆盖到之前覆盖过的连续的区间(其实就是将以前混合的区间合并成一个) 这是更新val所必须的

但如此做了我们会发现val只计算到了更新过的位置 无法将这次更新down下去 那么就需要设置一个lazy标志

lazy记录该区间还没有被down下去的价值


代码:

#include
  
   
#include
   
     #include
    
      using namespace std; #define N 101000 #define L(x) (x<<1) #define R(x) ((x<<1)|1) typedef __int64 ll; int n,m; struct node { int l,r,cov; ll val,lazy; }tree[N*4]; ll ans; int abs(int x) { if(x<0) return -x; return x; } void up(int i) { tree[i].val=tree[L(i)].val+tree[R(i)].val; } void down(int i) { if(tree[i].cov) { tree[L(i)].cov=tree[i].cov; tree[R(i)].cov=tree[i].cov; tree[i].cov=0; } if(tree[i].lazy) { tree[L(i)].lazy+=tree[i].lazy; tree[L(i)].val+=tree[i].lazy*(tree[L(i)].r-tree[L(i)].l+1); tree[R(i)].lazy+=tree[i].lazy; tree[R(i)].val+=tree[i].lazy*(tree[R(i)].r-tree[R(i)].l+1); tree[i].lazy=0; } } void init(int l,int r,int i) { tree[i].l=l; tree[i].r=r; tree[i].val=tree[i].lazy=0; if(l==r) { tree[i].cov=l; return ; } int mid=(l+r)/2; init(l,mid,L(i)); init(mid+1,r,R(i)); } void solve(int i,int key) { if(tree[i].cov) { tree[i].lazy+=abs(key-tree[i].cov); tree[i].val+=(ll)(abs(key-tree[i].cov))*(tree[i].r-tree[i].l+1); tree[i].cov=key; return ; } else { down(i); solve(L(i),key); solve(R(i),key); up(i); } tree[i].cov=key; } void update(int l,int r,int i,int key) { if(tree[i].l==l&&tree[i].r==r) { solve(i,key); return ; } down(i); int mid=(tree[i].l+tree[i].r)/2; if(r<=mid) update(l,r,L(i),key); else if(l>mid) update(l,r,R(i),key); else { update(l,mid,L(i),key); update(mid+1,r,R(i),key); } up(i); } void query(int l,int r,int i) { if(tree[i].l==l&&tree[i].r==r) { ans+=tree[i].val; return ; } down(i); int mid=(tree[i].l+tree[i].r)/2; if(r<=mid) query(l,r,L(i)); else if(l>mid) query(l,r,R(i)); else { query(l,mid,L(i)); query(mid+1,r,R(i)); } up(i); } int main() { int p,l,r,w; scanf("%d%d",&n,&m); init(1,n,1); while(m--) { scanf("%d%d%d",&p,&l,&r); if(p==1) { scanf("%d",&w); update(l,r,1,w); } else { ans=0; query(l,r,1); printf("%I64d\n",ans); } } return 0; }
    
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇UVA Mapping the Swaps 下一篇HihoCoder――Trie树

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: