WA首次实现了分段树

时间:2014-12-29 11:40:58

标签: tree segment-tree acm

这是我第一次在问题中实现和使用段树,我需要你的帮助来解决我的第一个问题ACd。这是问题 - http://www.codechef.com/problems/ACM14KN4

这是我的解决方案,它给出了WA -

(由于这是我的实现,并不是完全证明,因为这是第一次进行测试,知道哪些功能可能无法正常工作并需要更正,这将是很好的)

#define maxn 801000

1)节点的结构

struct node{
int flagi = 0,flagd = 0;
int mini=INT_MAX,maxi=INT_MIN;
int sum = 0;
}tree[4*maxn];

2)构建功能

void build (int a[],int n,int l,int r){
// n should be 1 while calling from main and tl = 0 and tr = no of elements - 1
if(l==r){
    tree[n].maxi=a[l];
    tree[n].mini=a[l];
    tree[n].flagi=1;
    tree[n].flagd=1;
    tree[n].sum = a[l];

    return;
}

int m = (l+r)/2;

build(a,2*n,l,m);
build (a,2*n+1,m+1,r);

tree[n].maxi=max(tree[2*n].maxi,tree[2*n+1].maxi);
tree[n].mini=min(tree[2*n].mini,tree[2*n+1].mini);
tree[n].sum = tree[2*n].sum + tree[2*n+1].sum;

if((tree[2*n].flagi & tree[2*n+1].flagi) && tree[2*n].maxi<=tree[2*n+1].mini)
tree[n].flagi=1;
else tree[n].flagi=0;

 if((tree[2*n].flagd & tree[2*n+1].flagd) && tree[2*n].mini>=tree[2*n+1].maxi)
tree[n].flagd=1;
else tree[n].flagd=0;



}

3)a)在范围内返回最大值的函数

int maximum(int n,int l,int r,int tl,int tr){
// n should be 1 while calling from main and tl = 0 and tr = no of elements - 1

if(l>r || tl>tr)
    return INT_MIN;

if(tl>r || tr<l)
    return INT_MIN;

if(tl>=l && tr<=r)
    return tree[n].maxi;

int tm = (tl+tr)/2;

return max(maximum(2*n,l,r,tl,tm),maximum(2*n+1,l,r,tm+1,tr));

}

3)b)在范围内返回最小值的函数

 int minimum(int n,int l,int r,int tl,int tr){
// n should be 0 while calling from main and tl = 0 and tr = no of elements - 1

//cout << " tl,tr,n "<< tl << ','<<tr<<','<<n << endl;

if(l>r || tl>tr)
    return INT_MAX;

if(tl>r || tr<l)
    return INT_MAX;

if(tl>=l && tr<=r)
    return tree[n].maxi;

int tm = (tl+tr)/2;

return min(minimum(2*n,l,r,tl,tm),minimum(2*n+1,l,r,tm+1,tr));

}

4)返回范围

中的和的函数
int sum (int n,int l,int r,int tl,int tr){
   //tl and tr represent the indices for which the current tree index i.e n holds the sum and
 // l and r are the query indices
// n should be 1 while calling from main and tl = 0 and tr = no of elements - 1

if(l>r || tl>tr)
    return 0;

if(tl>r || tr<l)
    return 0;

if(tl>=l && tr<=r)
    return tree[n].sum;

int tm = (tl+tr)/2;

return sum(2*n,l,r,tl,tm) + sum(2*n+1,l,r,tm+1,tr);

}

5)如果元素在给定范围内递增,则返回1的函数

int inc(int n,int l,int r,int tl,int tr){

if(l>r || tl>tr)
    return 1;

if(tl>r || tr<l)
    return 1;

if(tl>=l && tr<=r){
 //   cout << "l,r,flag" << l << " , " << r << " , " << tree[n].flagi << endl;
    return tree[n].flagi;
}
int tm = (tl+tr)/2;

int lmax = maximum(2*n,l,r,tl,tm);
int rmin = minimum(2*n+1,l,r,tm+1,tr);

int ans = 0;

if(lmax<=rmin)
    ans = 1;

int range_flag = inc(2*n,l,r,tl,tm)&inc(2*n+1,l,r,tm+1,tr);


//cout << "l,r,flag" << l << " , " << r << " , " << ans << endl;

return ans&range_flag;

}

6)如果元素在给定范围内递增,则返回1的函数

int dec(int n,int l,int r,int tl,int tr){

if(l>r || tl>tr)
    return 1;

if(tl>r || tr<l)
    return 1;

if(tl>=l && tr<=r){
   // cout << "l,r,flag" << l << " , " << r << " , " << tree[n].flagd << endl;
    return tree[n].flagd;
}
int tm = (tl+tr)/2;

int lmin = minimum(2*n,l,r,tl,tm);
int rmax = maximum(2*n+1,l,r,tm+1,tr);

int ans = 0;

if(lmin>=rmax)
    ans = 1;

int range_flag = dec(2*n,l,r,tl,tm)&dec(2*n+1,l,r,tm+1,tr);


//cout << "l,r,flag" << l << " , " << r << " , " << ans << endl;

return ans&range_flag;

}

7)更新功能

void update(int n,int tl,int tr,int old,int val,int index){

if(index>tr || index<tl)
    return;

if(tl==tr){
    //cout << " tl,tr,diff " << tl << " , " << tr << " , " << diff << endl;
    tree[n].sum=val;
    tree[n].maxi=val;
    tree[n].mini=val;
    tree[n].flagi=1;
    tree[n].flagd=1;
    return;
}

int tm = (tl+tr)/2;


 update(2*n,tl,tm,old,val,index);
 update(2*n+1,tm+1,tr,old,val,index);


if(index>=tl && index<=tr){

    tree[n].maxi=max(tree[2*n].maxi,tree[2*n+1].maxi);
    tree[n].mini=min(tree[2*n].mini,tree[2*n+1].mini);
    tree[n].sum=tree[2*n].sum + tree[2*n+1].sum;

if((tree[2*n].flagi & tree[2*n+1].flagi) && tree[2*n].maxi<=tree[2*n+1].mini)
    tree[n].flagi=1;
else
    tree[n].flagi=0;

 if((tree[2*n].flagd & tree[2*n+1].flagd) && tree[2*n].mini>=tree[2*n+1].maxi)
tree[n].flagd=1;
else tree[n].flagd=0;


    //cout << " tl,tr,diff " << tl << " , " << tr << " , " << diff << endl;
}
}

8)主要 -

int main () {

int n,q;
char choice;

ios_base::sync_with_stdio(false);

cin >> n >> q;
int a[n];

for(int i=0;i<n;i++)
cin >> a[i];

build(a,1,0,n-1);


for(int i=0,j=0,k=0;i<q;i++){
//cout << "1.update\n2.max in range\n3.sum\n4.increasing order\n";
cin >> choice >> j >> k;

if(choice=='U'){
update(1,0,n-1,a[i],k,j-1);
a[i]=k;
}

else if(choice=='M')
cout << maximum(1,j-1,k-1,0,n-1) << endl;

else if(choice=='S')
cout << sum(1,j-1,k-1,0,n-1) << endl;


 else if(choice=='I')
cout << inc(1,j-1,k-1,0,n-1) << endl;

else if(choice=='D')
cout << dec(1,j-1,k-1,0,n-1) << endl;

}

return 0;

}

0 个答案:

没有答案