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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

201709-5 除法 ccf(树状数组)

發(fā)布時(shí)間:2023/12/15 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 201709-5 除法 ccf(树状数组) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

問題描述
  小蔥喜歡除法,所以他給了你N個(gè)數(shù)a1, a2, ?, aN,并且希望你執(zhí)行M次操作,每次操作可能有以下兩種:
  給你三個(gè)數(shù)l, r, v,你需要將al, al+1, ?, ar之間所有v的倍數(shù)除以v。
  給你兩個(gè)數(shù)l, r,你需要回答al + al+1 + ? + ar的值是多少。
  
輸入格式
  第一行兩個(gè)整數(shù)N, M,代表數(shù)的個(gè)數(shù)和操作的次數(shù)。
  接下來(lái)一行N個(gè)整數(shù),代表N個(gè)數(shù)一開始的值。

輸出格式
  對(duì)于每一次的第二種操作,輸出一行代表這次操作所詢問的值。
樣例輸入

5 3
1 2 3 4 5
2 1 5
1 1 3 2
2 1 5
1
2
3
4
5
樣例輸出

15
14
1
2
評(píng)測(cè)用例規(guī)模與約定
  對(duì)于30%的評(píng)測(cè)用例,1 ≤ N, M ≤ 1000;
  對(duì)于另外20%的評(píng)測(cè)用例,第一種操作中一定有l(wèi) = r;
  對(duì)于另外20%的評(píng)測(cè)用例,第一種操作中一定有l(wèi) = 1 , r = N;
  對(duì)于100%的評(píng)測(cè)用例,1 ≤ N, M ≤ 105,0 ≤ a1, a2, ?, aN ≤ 106, 1 ≤ v ≤ 106, 1 ≤ l ≤ r ≤ N。
一開始看這個(gè)題,就是線段樹嘛,我還想最后一個(gè)題目怎么這么簡(jiǎn)單.就寫了線段樹,提交了一發(fā),超時(shí)了.好吧1e6的數(shù)據(jù),不超時(shí)才怪…才想起來(lái)的樹狀數(shù)組,今天才發(fā)現(xiàn)她的魅力.時(shí)間復(fù)雜度O(logn),空間復(fù)雜度O(n).怎么會(huì)有這么好的東西…比線段樹足足提高了一個(gè)檔次.兩個(gè)代碼都粘一下吧,畢竟線段樹寫了很久,第一次正兒八經(jīng)的自己寫線段樹.
超時(shí)線段樹:

#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std;const int maxx=1e5+10; int ary[maxx]; struct node{int l;int r;int sum; }p[maxx*4]; int n,m;void pushup(int cur) {p[cur].sum=p[2*cur].sum+p[2*cur+1].sum; }void build(int l,int r,int cur) {p[cur].l=l;p[cur].r=r;p[cur].sum=0;if(l==r){p[cur].sum=ary[l];return ; }int mid=(l+r)/2;build(l,mid,2*cur);build(mid+1,r,2*cur+1);pushup(cur); }int query(int l,int r,int cur) {if(l<=p[cur].l&&r>=p[cur].r){return p[cur].sum;}int mid=(p[cur].l+p[cur].r)/2;if(mid>=r) return query(l,r,2*cur);else if(mid<l) return query(l,r,2*cur+1);else return query(l,mid,2*cur)+query(mid+1,r,2*cur+1); }void update(int L,int R,int v,int cur) {int l=p[cur].l;int r=p[cur].r;if(l==r&&l<=l&&l<=R){//cout<<p[cur].sum<<endl;if(p[cur].sum%v==0) p[cur].sum/=v;return ;}int mid=(l+r)/2;if(mid>=R) update(L,R,v,2*cur);else if(mid<L) update(L,R,v,2*cur+1);else{update(L,mid,v,2*cur);update(mid+1,R,v,2*cur+1);}pushup(cur); }int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%d",&ary[i]);build(1,n,1);int t,l,r,v;while(m--){scanf("%d",&t);if(t==1){scanf("%d%d%d",&l,&r,&v);update(l,r,v,1);}else if(t==2){scanf("%d%d",&l,&r);cout<<query(l,r,1)<<endl;}} }

樹狀數(shù)組:
樹狀數(shù)組就是跳躍著去找有關(guān)聯(lián)的一些點(diǎn),而不像線段樹那樣去二分找點(diǎn),這樣就大大的節(jié)省了時(shí)間.而且在空間上不需要開結(jié)構(gòu)體,也節(jié)省空間.

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define ll long long using namespace std;const int maxx=1e5+10; ll ary[maxx]; ll tree[maxx]; int n,m;int lowbit(int i)//樹狀數(shù)組的精華 {return i&-i; }ll getsum(int i) {ll sum=0;while(i>0){sum+=tree[i];i-=lowbit(i);}return sum; }void update(int i,int x) {while(i<=n){tree[i]+=x;i+=lowbit(i);} }int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&ary[i]);update(i,ary[i]);}int t,l,r,v;while(m--){scanf("%d",&t);if(t==1){scanf("%d%d%d",&l,&r,&v);while(l<=r){if(ary[l]%v==0){update(l,-(ary[l]-ary[l]/v));ary[l]=ary[l]/v;}++l;}}else if(t==2){scanf("%d%d",&l,&r);printf("%lld\n",getsum(r)-getsum(l-1));}} }

努力加油a啊,(o)/~

總結(jié)

以上是生活随笔為你收集整理的201709-5 除法 ccf(树状数组)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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