这是我第一次在问题中实现和使用段树,我需要你的帮助来解决我的第一个问题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;
}