1. 程式人生 > >線段樹非遞迴實現

線段樹非遞迴實現

程式碼:

#include <iostream>           //線段樹。  using namespace std; const int inf=100007; int Sum[inf<<2];           //初始的應該是零吧。   int Add[inf<<2]; int A[inf]; int n,N;

void Build(int n)          //首先進行建立。  {     N=1;while(N<n+2)N<<=1;  //首先找出N來。      for(int i=1;i<=n;i++)             Sum[i+N]=A[i];     //之後看看兩邊的還要管嗎。       for(int i=N-1;i>0;i--)     {         Sum[i]=Sum[i<<1]+Sum[i<<1|1];         Add[i]=0;          //在這裡進行修改嗎。        }       } void Update(int L,int C)           //之後是進行點修改。sum[l]+=C;  {     for(int s=L+N;s;s>>=1)     {         Sum[s]+=C;     } } int Query(int L,int R)       //點修改下的區間查詢。sum[L R]的和。  {     int ans=0;     for(int s=L+N-1,t=R+N+1;s^t^1;s>>=1,t>>=1)     {         if(~s&1)ans+=Sum[s^1];         if(t&1)ans+=Sum[t^1];     }     return ans; } void Update1(int L,int R,int C)   //區間修改Sum[L R]+=C;  {     int s,t,Ln=0,Rn=0,x=1;     for(s=L+N-1,t=R+N+1;s^t^1;s>>=1,t>>=1,x<<=1 )     {         Sum[s]+=Ln*C;         Sum[t]+=Ln*C;       //這裡。          if(~s&1)Add[s^1]+=C,Sum[s^1]+=C*x,Ln+=x;          if(t&1) Add[t^1]+=C,Sum[t^1]+=C*x,Rn+=x;     }     for( ;s;s>>=1,t>>=1)    //連結還是巧妙的啊。      {         Sum[s]+=C*Ln;                 Sum[t]+=C*Rn;     } } int Query1(int L,int R)        //區間修改上的區間查詢。sum【L,R】的和。  {     int s,t,Ln=0,Rn=0,x=1;     int ans=0;     for(s=L+N-1,t=R+N+1;s^t^1;s>>=1,t>>=1,x<<=1)     {         if(Add[s])ans+=Add[s]*Ln;         if(Add[t])ans+=Add[t]*Rn;          if(~s&1)ans+=Sum[s^1],Ln+=x;         if( t&1)ans+=Sum[t^1],Rn+=x;     }     for( ;s;s>>=1,t>>=1)                    //其實加不加是無所謂的。               {         /*if( Add[s])*/ans+=Add[s]*Ln;        //這裡為何是不加的呢。               /*if( Add[t])*/ans+=Add[t]*Rn;                             }     return ans;                                  }

int main() {      cout<<"請輸入陣列的個數"<<endl;      cin>>n;      cout<<"請輸入陣列中的值"<<endl;      for(int i=1;i<=n;i++)          cin>>A[i];      Build(n);   //初始化。       for(int i=1;i<=2*N-1;i++)               cout<<Sum[i]<<" ";         cout<<endl;     Update(3,1);     for(int i=1;i<=2*N-1;i++)         cout<<Sum[i]<<" ";         cout<<endl;     int ans=Query(2,4);         cout<<ans<<endl;     Update1(2,4,1);     for(int i=1;i<=2*N-1;i++)         cout<<Sum[i]<<" ";         cout<<endl;     int ans1=Query1(1,4);                //最後一個。               cout<<ans1<<endl;     return 0;  }