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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

ACM入门之【树状数组习题】

發布時間:2025/3/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ACM入门之【树状数组习题】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 130. 樹狀數組 1 :單點修改,區間查詢
  • 131. 樹狀數組 2 :區間修改,單點查詢
  • 132. 樹狀數組 3 :區間修改,區間查詢
  • 133. 二維樹狀數組 1:單點修改,區間查詢
  • 134. 二維樹狀數組 2:區間修改,單點查詢
  • 135. 二維樹狀數組 3:區間修改,區間查詢
  • P1908 逆序對

130. 樹狀數組 1 :單點修改,區間查詢


https://loj.ac/p/130

#include<bits/stdc++.h> using namespace std; const int N=1e6+10; typedef long long int LL; LL tr[N],n; int lowbit(int x){return x&(-x);} void add(int u,int x)//u位置加x {for(int i=u;i<=n;i+=lowbit(i)) tr[i]+=x; } LL query(int u)//求[1,u]的和 {LL sum=0;for(int i=u;i;i-=lowbit(i)) sum+=tr[i];return sum; } int main(void) {cin>>n>>m;for(int i=1;i<=n;i++){int x; cin>>x;add(i,x);}for(int i=0;i<m;i++){int op,a,b; cin>>op>>a>>b;if(op==1) add(a,b);else cout<<query(b)-query(a-1)<<endl;}return 0; }

131. 樹狀數組 2 :區間修改,單點查詢


https://loj.ac/p/131

#include<bits/stdc++.h> using namespace std; const int N=1e6+10; typedef long long int LL; LL tr[N],a[N],n,m; int lowbit(int x){return x&(-x);} void add(int u,int x)//u位置加x {for(int i=u;i<=n;i+=lowbit(i)) tr[i]+=x; } LL query(int u)//求點u的值 {LL sum=0;for(int i=u;i;i-=lowbit(i)) sum+=tr[i];return sum; } void init()//初始化差分數列 {for(int i=1;i<=n;i++) add(i,a[i]-a[i-1]); } void solve(int l,int r,int x)//[l,r]加x {add(l,x),add(r+1,-x); }int main(void) {cin>>n>>m;for(int i=1;i<=n;i++) cin>>a[i];init();for(int i=0;i<m;i++){int op; cin>>op;if(op==1){int l,r,x; cin>>l>>r>>x;solve(l,r,x);} else {int x; cin>>x;cout<<query(x)<<endl;}}return 0; }

132. 樹狀數組 3 :區間修改,區間查詢

#include<bits/stdc++.h> using namespace std; const int N=1e6+10; typedef long long int LL; LL tr1[N],tr2[N],a[N],n,m; LL lowbit(LL x){return x&(-x);} void add(LL tr[],LL u,LL c) {for(int i=u;i<=n;i+=lowbit(i)) tr[i]+=c; } LL query(LL tr[],LL u) {LL sum=0;for(int i=u;i;i-=lowbit(i)) sum+=tr[i];return sum; } LL sum(LL u) {return 1ll*(u+1)*query(tr1,u)-query(tr2,u); } void init()//初始化 {for(int i=1;i<=n;i++){add(tr1,i,a[i]-a[i-1]);add(tr2,i,i*(a[i]-a[i-1]));} } void add_lr(LL l,LL r,LL c)//[l,r]區間內加c {add(tr1,l,c),add(tr1,r+1,-c);add(tr2,l,l*c),add(tr2,r+1,-(r+1)*c); } LL query_lr(LL l,LL r)//查詢區間[l,r] {return sum(r)-sum(l-1); } int main(void) {cin>>n>>m;for(int i=1;i<=n;i++) cin>>a[i];init();for(int i=0;i<m;i++){int op; cin>>op;if(op==1){LL l,r,c; cin>>l>>r>>c;add_lr(l,r,c);}else{LL l,r; cin>>l>>r;cout<<query_lr(l,r)<<endl;}}return 0; }

133. 二維樹狀數組 1:單點修改,區間查詢

#include<bits/stdc++.h> using namespace std; const int N=5050; typedef long long int LL; LL tr[N][N],n,m; int lowbit(int x){return x&(-x);} void add(int x,int y,int v)//[x,y]加v {for(int i=x;i<=n;i+=lowbit(i))for(int j=y;j<=m;j+=lowbit(j))tr[i][j]+=v; } LL query(int x,int y) {LL sum=0; for(int i=x;i;i-=lowbit(i))for(int j=y;j;j-=lowbit(j)) sum+=tr[i][j];return sum; } LL query_ans(int x,int y,int xx,int yy) //找[x,y][xx,yy]為左上角和右下角的矩陣的和 {return query(xx,yy)-query(xx,y-1)-query(x-1,yy)+query(x-1,y-1); } int main(void) {cin>>n>>m;int op;while(cin>>op){if(op==1){int x,y,k; cin>>x>>y>>k;add(x,y,k);}else {int x,y,xx,yy; cin>>x>>y>>xx>>yy;cout<<query_ans(x,y,xx,yy)<<endl;}}return 0; }

134. 二維樹狀數組 2:區間修改,單點查詢

#include<bits/stdc++.h> using namespace std; const int N=5050; typedef long long int LL; LL tr[N][N],n,m; int lowbit(int x){return x&(-x);} void add(int x,int y,int v)//[x,y]加v {for(int i=x;i<=n;i+=lowbit(i))for(int j=y;j<=m;j+=lowbit(j))tr[i][j]+=v; } LL query(int x,int y)//單點查詢 {LL sum=0; for(int i=x;i;i-=lowbit(i))for(int j=y;j;j-=lowbit(j)) sum+=tr[i][j];return sum; } void add1(int x,int y,int xx,int yy,int k)//區間加 {add(x,y,k),add(xx+1,y,-k);add(x,yy+1,-k),add(xx+1,yy+1,k); } int main(void) {cin>>n>>m;int op; while(cin>>op){if(op==1){int x,y,xx,yy,c; cin>>x>>y>>xx>>yy>>c;add1(x,y,xx,yy,c);}else{int x,y; cin>>x>>y;cout<<query(x,y)<<endl;}}return 0; }

135. 二維樹狀數組 3:區間修改,區間查詢

#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 5000 + 10; LL t1[N][N],t2[N][N],t3[N][N],t4[N][N]; int n,m; int lowbit(int x) {return x & - x;} void add(int a, int b, int k) {for (int i = a; i <= n; i += lowbit(i)) {for (int j = b; j <= m; j += lowbit(j)) {t1[i][j] += k;t2[i][j] += k * a;t3[i][j] += k * b;t4[i][j] += k * a * b;}} } LL sum(int a, int b) {LL ans=0;for (int i=a;i;i-=lowbit(i))for (int j=b;j;j-=lowbit(j))ans+=t1[i][j]*((a+1)*(b+1))-t2[i][j]*(b+1)-t3[i][j]*(a+1)+t4[i][j];return ans; } void add1(int a,int b,int c,int d,int k) //[a,b][c,d]為左上角和右下角的矩陣所有值加k {add(a, b, k);add(c + 1, d + 1, k);add(a, d + 1, -k);add(c + 1, b, -k); } LL query_ans(int a,int b,int c,int d) //求區間[a,b],[c,d]為左上角和右下角的和 {return sum(a-1,b-1)+sum(c,d)-sum(a-1,d)-sum(c,b-1); } int main() {scanf("%d%d",&n,&m);int op,a,b,c,d,k;while(~scanf("%d", &op)){if(op==1) {scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);add1(a,b,c,d,k);} else {scanf("%d%d%d%d",&a,&b,&c,&d);printf("%lld\n",query_ans(a,b,c,d));}}return 0; }

P1908 逆序對

#include<bits/stdc++.h> using namespace std; const int N=1e6+10; typedef long long int LL; int a[N],tr[N],n; vector<int>ve; int lowbit(int x){return x&(-x);} void add(int u,int v) {for(int i=u;i<=n;i+=lowbit(i)) tr[i]+=v; } LL query(int u) {LL sum=0;for(int i=u;i;i-=lowbit(i)) sum+=tr[i];return sum; } int main(void) {cin>>n;for(int i=1;i<=n;i++) scanf("%d",&a[i]);for(int i=1;i<=n;i++) ve.push_back(a[i]);sort(ve.begin(),ve.end());ve.erase(unique(ve.begin(),ve.end()),ve.end());LL ans=0;for(int i=1;i<=n;i++){int l=upper_bound(ve.begin(),ve.end(),a[i])-ve.begin();//找到第一個大于a[i]的下標,從0開始ans+=query(n)-query(l);add(l,1);}cout<<ans;return 0; } 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的ACM入门之【树状数组习题】的全部內容,希望文章能夠幫你解決所遇到的問題。

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