日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2023/12/9 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces 444C 节点更新求变化值的和 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

題目大意:

給定一列n個數(shù)字,最初賦予值1到n

兩個操作:
1.將區(qū)間[l,r]內(nèi)的數(shù)改為x,則這區(qū)間中所有數(shù)的改變值進行求和,即ans=abs(a[l]-x)+abs[a[l+1]-x).....abs(a[r]-x),但不要求輸出

2.需要將剛才要求得到的區(qū)間改變值輸出出來

?

這里我們利用一個color[]數(shù)組相當于給這堆數(shù)進行染色,當某個區(qū)間內(nèi)的賦予的值相等時,我們可以看做有一個相同的color[]=val了,這樣我們可以直接對這個區(qū)間

利用乘法求改變值。

這樣的話,我們還需要一個數(shù)組del[]時刻記錄每個量改變的差值

sum[]數(shù)組的話就是用來保存區(qū)間改變量的和

?

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 }

?

轉(zhuǎn)載于:https://www.cnblogs.com/CSU3901130321/p/3898384.html

總結(jié)

以上是生活随笔為你收集整理的CodeForces 444C 节点更新求变化值的和的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。