题意:一个圆环上有树,猴子上下其中一棵树,再沿着换跑,再上下另一棵树。给出一个区间,问最大的运动距离是。
给出区间大小dst,和数高数组arr。
设区间[x,y],a[x]=2*arr[x]+dst[1]+dst[2]+......dst[x]。b[x]=2*arr[x]-dst[1]-dst[2]-......dst[x]。[x,y]在线段树中就是a[y]+b[x]。线段树分为很多区间,用数组a,b,s,记录当前区间的a,b最大值,s记录该区间里所有的情况中的爬树+路程的最大值,就是两个子区间中a最大的和b最大的。叶子节点用上面的公式计算。叶子节点s为0,其它的要么区间的最大值来自子区间的s值,要么是左区间的a值+右区间的b值,或者左的b值+右的a,以上几个的最大值。查询的时候查s值。查询结果要返回a,b,s。比如查[1,3]分为[1,2]和[3],那么结果是[1,2]的s,[3]的s,[1,2]的a+[3]的b,[1,2]的b+[3]的a,以上的最大值。因此a,b,c都要返回。
乱码:
#pragma comment(linker,"/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> #include <stack> using namespace std; const int SZ=8e5+10,INF=0x7FFFFFFF; typedef long long lon; lon mod=1000000009; lon srcdst[SZ],dst[SZ],tall[SZ],a[SZ],b[SZ],s[SZ],arr[SZ]; lon n,m; void init(lon n) { for(lon i=2;i<=n+1;++i) { cin>>dst[i]; } for(lon i=n+2;i<2*n+1;++i) { dst[i]=dst[i-n]; } for(lon i=2;i<=2*n+1;++i) { dst[i]+=dst[i-1]; } for(lon i=1;i<=n;++i)cin>>arr[i]; } void pushup(lon rt) { a[rt]=max(a[rt*2],a[rt*2+1]); b[rt]=max(b[rt*2],b[rt*2+1]); lon m1=max(s[rt*2],s[rt*2+1]); lon m2=max(a[rt*2]+b[rt*2+1],a[rt*2+1]+b[rt*2]); s[rt]=max(m1,m2); } void build(lon ll,lon rr,lon rt) { if(ll==rr) { lon real=(ll-1)%(n/2)+1; a[rt]=2*arr[real]+dst[ll]; b[rt]=2*arr[real]-dst[ll]; //cout<<ll<<" "<<a[rt]<<" "<<b[rt]<<endl; return; } if(ll>rr)return; lon mid=(ll+rr)/2; build(ll,mid,rt*2); build(mid+1,rr,rt*2+1); pushup(rt); } struct nd{ lon a,b,s; nd (lon _a=0,lon _b=0,lon _s=0):a(_a),b(_b),s(_s){} bool operator==(const nd &rbs)const { return a==rbs.a&&b==rbs.b&&s==rbs.s; } }; nd qry(lon ll,lon rr,lon ql,lon qr,lon rt) { nd res1,res2,rbs; if(ll>=ql&&rr<=qr) { nd tmp; tmp.a=a[rt],tmp.b=b[rt],tmp.s=s[rt]; return tmp; } //cout<<ll<<" "<<rr<<" "<<ql<<" "<<qr<<endl; if(rr<ql||ll>qr)return rbs; lon mid=(ll+rr)/2; if(rr>=ql)res1=qry(ll,mid,ql,qr,rt*2); if(ll<=qr)res2=qry(mid+1,rr,ql,qr,rt*2+1); if(res1==rbs)return res2; else if(res2==rbs)return res1; else { lon max1=max(res1.s,res2.s); lon max2=max(res1.a+res2.b,res1.b+res2.a); res1.s=max(max1,max2); res1.a=max(res1.a,res2.a); res1.b=max(res1.b,res2.b); return res1; } } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); cin>>n>>m; init(n); n=2*n+1; build(1,n,1); for(lon i=0;i<m;++i) { lon ql,qr; cin>>ql>>qr; if(ql<=qr) { swap(ql,qr); ++ql; qr+=n/2-1; } else { swap(ql,qr); ++ql,--qr; } cout<<qry(1,n,ql,qr,1).s<<endl; } return 0; }