CodeForces 444C 节点更新求变化值的和
生活随笔
收集整理的這篇文章主要介紹了
CodeForces 444C 节点更新求变化值的和
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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 }?
轉載于:https://www.cnblogs.com/CSU3901130321/p/3898384.html
總結
以上是生活随笔為你收集整理的CodeForces 444C 节点更新求变化值的和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Navicat 远程连接ubuntu出现
- 下一篇: 太极