日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Hud 敌兵布阵 --线段树的插点问线

發(fā)布時間:2025/3/18 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hud 敌兵布阵 --线段树的插点问线 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

???? 每個樹存放的事左右端點的的總和,然后再遞歸往下分成更小的區(qū)間,根據(jù)著2*t是下一層節(jié)點的節(jié)點端點是(left,left+right)/2);2*t+1是右節(jié)點的區(qū)間是(left+right)/2+1,right);

而更新的時候就是把點當成是(x,x)這樣的區(qū)間然后去尋找它所在區(qū)間的葉子節(jié)點,然后回溯把所有祖先的區(qū)間都更新了,然后即使查找的了,當你查找的區(qū)間是(l,r)時,你先是從最大的區(qū)間開始去查找也就是從節(jié)點等于一開始查找看是否與所求的區(qū)間相等,不等時有三種可能就是在左右節(jié)點或者是左右節(jié)點的區(qū)間各有一半,然后就分開討論。

?

#include<stdio.h> #include<string.h> #define mid(x,y) (x+y)/2 int v,b; int a[500005],ans,cnt; struct app {int left,right;int sum; }tree[500000]; void build_tree(int left,int right,int t) //建樹,l,r是區(qū)間的左右端點數(shù),t是每次從從1開始然后繁衍兒子 {int x;tree[t].left=left;tree[t].right=right;tree[t].sum=0;if(left==right){ //當它已經(jīng)是葉子了不能在繁衍了就開始回溯讓它的所有祖先都加上兒子(敵營)的人數(shù)while(t!=0) {tree[t].sum+=a[left];t/=2; //下一個祖先}return ;}x=mid(left,right);build_tree(left,x,2*t); //對每個區(qū)間不斷的遞歸讓它們能不斷分離下去,注意哦,這里是不斷找出每個區(qū)間的左區(qū)間,直到找完了再開始從頭找右節(jié)點 build_tree(x+1,right,2*t+1); }void updata_tree(int left,int right,int t) //更新線段樹,先找到所更新點的葉子,然后再把此點和所有的祖先區(qū)間都更新 {if(tree[t].left==left&&tree[t].right==right){while(t!=0){tree[t].sum+=cnt;t/=2;}return ;}int x=mid(tree[t].left,tree[t].right);if(x>=right) // 分到的點可以鎖定在右邊的區(qū)間所以,關(guān)鍵在2*t著才是代表在右邊updata_tree(left,right,2*t);else if(x+1<=left)updata_tree(left,right,2*t+1);else{updata_tree(left,x,2*t);updata_tree(x+1,right,2*t+1);} }void query_tree(int left,int right,int t) //查找區(qū)間如果是在區(qū)間里面的就直接把和加上,如果是是在左右區(qū)間的中間那就分開加直到你加到你查找的區(qū)間被包含在現(xiàn)有的區(qū)間內(nèi),就結(jié)束了然后把你所經(jīng)歷的區(qū)間的值加起來就是結(jié)果了 {if(tree[t].left==left&&tree[t].right==right){ans+=tree[t].sum;return ;}int x=mid(tree[t].left,tree[t].right);if(x>=right){query_tree(left,right,2*t);}else if(x+1<=left)query_tree(left,right,2*t+1);else{query_tree(left,x,2*t);query_tree(x+1,right,2*t+1);} }int main() {int t,n,i,j;scanf("%d",&t);for(i=1;i<=t;i++){printf("Case %d:\n",i);scanf("%d",&n);memset(a,0,sizeof(a));for(j=1;j<=n;j++)scanf("%d",&a[j]);build_tree(1,n,1);char sh[10];while(1){scanf("%s",sh);if(sh[0]=='E')break;if(sh[0]=='A'){scanf("%d%d",&v,&cnt);updata_tree(v,v,1);}if(sh[0]=='Q'){scanf("%d%d",&v,&b);ans=0;query_tree(v,b,1);printf("%d\n",ans);}if(sh[0]=='S'){scanf("%d%d",&v,&cnt);cnt=-cnt;updata_tree(v,v,1);}}}return 0; }

總結(jié)

以上是生活随笔為你收集整理的Hud 敌兵布阵 --线段树的插点问线的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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