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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

UOJ228:基础数据结构练习题——题解

發布時間:2025/7/25 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UOJ228:基础数据结构练习题——题解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://uoj.ac/problem/228

參考:https://www.cnblogs.com/ljh2000-jump/p/6357583.html

考慮當整個區間的最大值開方==最小值開方(實質上就是區間開完方后所有數都相等),那么我們開一次方就可以了。

聽說有證明如果達到上面的那種情況的話最多需要操作O(lg^2)次,那么復雜度就是O(n*lg^3)了。

實際上開方只是起到了一個縮小最大值和最小值差值的作用,當差值縮小為0時就是我們所想要的那種情況。

但是也有極端數據比如898989,開完方變成343434……無限下去你就會發現無論怎么開所有的數都會差1,復雜度瞬間被艸。

對于這種極端數據實際上只是進行了一次區間減,我們特判之就能保證復雜度了。

另外為了減少代碼編寫難度,采用了參考的那種只有當最大值==最小值才開方的寫法,雖然最好情況下復雜度會增加,但是最壞情況復雜度并沒有增加,所以沒有問題。

#include<map> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<vector> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=1e5+5; inline ll read(){ll X=0,w=0;char ch=0;while(!isdigit(ch)){w|=ch=='-';ch=getchar();}while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } int n,m; ll b[N],sum[N*4],ad[N*4],maxn[N*4],minn[N*4]; inline void mdy(int a,int l,int r,ll w){sum[a]+=w*(r-l+1);maxn[a]+=w;minn[a]+=w;ad[a]+=w; } inline void upt(int a,int l,int r){int ls=a<<1,rs=a<<1|1;sum[a]=sum[ls]+sum[rs]+ad[a]*(r-l+1);maxn[a]=max(maxn[ls],maxn[rs])+ad[a];minn[a]=min(minn[ls],minn[rs])+ad[a]; } void build(int a,int l,int r){if(l==r){sum[a]=maxn[a]=minn[a]=b[l];return;}int mid=(l+r)>>1;build(a<<1,l,mid);build(a<<1|1,mid+1,r);upt(a,l,r); } void seg_add(int a,int l,int r,int l1,int r1,ll w){if(r<l1||r1<l)return;if(l1<=l&&r<=r1){mdy(a,l,r,w);return;}int mid=(l+r)>>1;seg_add(a<<1,l,mid,l1,r1,w);seg_add(a<<1|1,mid+1,r,l1,r1,w);upt(a,l,r); } void seg_sqrt(int a,int l,int r,int l1,int r1,ll w){if(r<l1||r1<l)return;if(l1<=l&&r<=r1){ll delta,c1=sqrt(minn[a]+w),c2=sqrt(maxn[a]+w);if(maxn[a]==minn[a]){delta=minn[a]+w-(ll)sqrt(minn[a]+w);mdy(a,l,r,-delta);return;}else if(minn[a]+1==maxn[a]&&c1+1==c2){delta=minn[a]+w-(ll)sqrt(minn[a]+w);mdy(a,l,r,-delta);return;}}int mid=(l+r)>>1;w+=ad[a];seg_sqrt(a<<1,l,mid,l1,r1,w);seg_sqrt(a<<1|1,mid+1,r,l1,r1,w);upt(a,l,r); } ll query(int a,int l,int r,int l1,int r1,ll w){if(r<l1||r1<l)return 0;if(l1<=l&&r<=r1)return sum[a]+w*(r-l+1);int mid=(l+r)>>1;w+=ad[a];return query(a<<1,l,mid,l1,r1,w)+query(a<<1|1,mid+1,r,l1,r1,w); } int main(){n=read(),m=read();for(int i=1;i<=n;i++)b[i]=read();build(1,1,n);while(m--){int op=read(),x=read(),y=read();if(op==1)seg_add(1,1,n,x,y,read());if(op==2)seg_sqrt(1,1,n,x,y,0);if(op==3)printf("%lld\n",query(1,1,n,x,y,0));}return 0; }

+++++++++++++++++++++++++++++++++++++++++++

?+本文作者:luyouqi233。               +

?+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

轉載于:https://www.cnblogs.com/luyouqi233/p/9154111.html

總結

以上是生活随笔為你收集整理的UOJ228:基础数据结构练习题——题解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。