码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 444C 节点更新求变化值的和

时间:2014-08-08 01:39:35      阅读:378      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   for   cti   div   

http://vjudge.net/problem/viewProblem.action?id=51622

题目大意:

给定一列n个数字,最初赋予值1到n

两个操作:
1.将区间[l,r]内的数改为x,则这区间中所有数的改变值进行求和,即ans=abs(a[l]-x)+abs[a[l+1]-x).....abs(a[r]-x),但不要求输出

2.需要将刚才要求得到的区间改变值输出出来

 

这里我们利用一个color[]数组相当于给这堆数进行染色,当某个区间内的赋予的值相等时,我们可以看做有一个相同的color[]=val了,这样我们可以直接对这个区间

利用乘法求改变值。

这样的话,我们还需要一个数组del[]时刻记录每个量改变的差值

sum[]数组的话就是用来保存区间改变量的和

 

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 #define N 100005
 5 #define LL long long
 6 #define L ls,x,mid
 7 #define R rs,mid+1,y
 8 LL color[N<<2],sum[N<<2],del[N<<2];
 9 LL abs(LL a)
10 {
11     return a>0?a:-a;
12 }
13 void push_up(int cur)
14 {
15     if(color[cur<<1]==color[cur<<1|1]) color[cur]=color[cur<<1];
16     else color[cur]=0;
17     sum[cur]=sum[cur<<1]+sum[cur<<1|1];
18 }
19 void push_down(int cur,int x,int y)
20 {
21     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
22     if(color[cur]){
23         color[ls]=color[rs]=color[cur];
24         del[ls]+=del[cur],del[rs]+=del[cur];
25         sum[ls]+=(mid-x+1)*del[cur];
26         sum[rs]+=(y-mid)*del[cur];
27         del[cur]=color[cur]=0;
28     }
29 }
30 void build(int cur,int x,int y)
31 {
32     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
33     if(x==y){
34         color[cur]=x;
35         sum[cur]=0;
36         return;
37     }
38     color[cur]=del[cur]=0;
39     build(L);
40     build(R);
41     push_up(cur);
42 }
43 void update(int cur,int x,int y,int s,int t,int v)
44 {
45     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
46     if(x>=s&&y<=t&&color[cur]){
47         sum[cur]+=abs(color[cur]-v)*(y-x+1);
48         //printf("%I64d\n",abs(color[cur]-v));
49         del[cur]+=abs(color[cur]-v);
50         color[cur]=v;
51         return;
52     }
53     push_down(cur,x,y);
54     if(mid>=s) update(L,s,t,v);
55     if(mid<t) update(R,s,t,v);
56     push_up(cur);
57 }
58 void query(int cur,int x,int y,int s,int t,LL &ans)
59 {
60     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
61     if(x>=s&&y<=t){
62         ans+=sum[cur];
63         return;
64     }
65     push_down(cur,x,y);
66     if(mid>=s) query(L,s,t,ans);
67     if(mid<t) query(R,s,t,ans);
68 }
69 int main()
70 {
71     int n,m,type,l,r,x;
72     scanf("%d%d",&n,&m);
73     build(1,1,n);
74     for(int i=0;i<m;i++)
75     {
76         scanf("%d",&type);
77         if(type==1){
78             scanf("%d%d%d",&l,&r,&x);
79             update(1,1,n,l,r,x);
80         }else{
81             scanf("%d%d",&l,&r);
82             LL ans=0;
83             query(1,1,n,l,r,ans);
84             printf("%I64d\n",ans);
85         }
86     }
87     return 0;
88 }

 

CodeForces 444C 节点更新求变化值的和,布布扣,bubuko.com

CodeForces 444C 节点更新求变化值的和

标签:style   blog   http   color   io   for   cti   div   

原文地址:http://www.cnblogs.com/CSU3901130321/p/3898384.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!