It seems not difficult for AC to have a hard question, but you need to think carefully,
The wrong idea at the beginning ---- is influenced by the longest continuous substring of the previously done range http://blog.csdn.net/u011026968/article/details/38357157
When merging intervals, I directly follow --- If (the maximum prefix and length of the Left subtree = the length of the Left subtree & the prefix of the right subtree and> 0 ), there are two mistakes in merging the left Prefix: 1. Is the interval to be merged when the right subtree prefix is equal to or equal to 0? The question requires that X be as small as possible. If X is the same as Y, it should be as small as possible (X is the left endpoint of ANS, Y is the right endpoint of ANS), 2. The left subtree interval is 3, 1,-2, if the range of the right subtree is 9, 5,-10, then the maximum root prefix and the left subtree interval + part of the right subtree must be 3, 1, 5. However, according to my initial code, interval merging is not performed here ..............
The correct method for merging intervals is,
If (prefix of the right subtree and + interval of the Left subtree and <= prefix and of the left subtree)
Root prefix and = left subtree prefix and
Else
Root prefix and = right subtree prefix and + Left subtree interval and
This ensures that X is as small as possible. If X is the same as Y, it is as small as possible (X is the left endpoint of the ANS range, and Y is the right endpoint of the ANS range)
Code above: has the opportunity to rewrite it with the longest consecutive substring of the Interval
#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <iostream>#include <cmath>#include <map>#include <queue>using namespace std;#define ls(rt) rt*2#define rs(rt) rt*2+1#define ll long long#define ull unsigned long long#define rep(i,s,e) for(int i=s;i<e;i++)#define repe(i,s,e) for(int i=s;i<=e;i++)#define CL(a,b) memset(a,b,sizeof(a))#define IN(s) freopen(s,"r",stdin)#define OUT(s) freopen(s,"w",stdin)const int MAXN = 500000+500;ll sum[MAXN],a[MAXN];struct Node{ int l,r; int ls,rs; int x,y; ll mx;}nodes[MAXN*4];inline ll cal(int a, int b){ return sum[a]-sum[b-1];}void pushup(int rt){ if(cal(nodes[ls(rt)].ls,nodes[rt].l) >= cal(nodes[rs(rt)].ls,nodes[rt].l)) nodes[rt].ls=nodes[ls(rt)].ls; else nodes[rt].ls=nodes[rs(rt)].ls; if(cal(nodes[rs(rt)].r,nodes[ls(rt)].rs) >= cal(nodes[rs(rt)].r,nodes[rs(rt)].rs)) nodes[rt].rs=nodes[ls(rt)].rs; else nodes[rt].rs=nodes[rs(rt)].rs; //cal mx ll vl=nodes[ls(rt)].mx; // lmx ll vr=nodes[rs(rt)].mx; //rmx ll vv=cal(nodes[rs(rt)].ls,nodes[ls(rt)].rs);//mid if(vl>=vr) { nodes[rt].x=nodes[ls(rt)].x; nodes[rt].y=nodes[ls(rt)].y; nodes[rt].mx=vl; } else { nodes[rt].x=nodes[rs(rt)].x; nodes[rt].y=nodes[rs(rt)].y; nodes[rt].mx=vr; } if(nodes[rt].mx<vv) { nodes[rt].x=nodes[ls(rt)].rs; nodes[rt].y=nodes[rs(rt)].ls; nodes[rt].mx=vv; } if(nodes[rt].mx == vv) { if(nodes[rt].x>nodes[ls(rt)].rs || (nodes[rt].x==nodes[ls(rt)].rs && nodes[rt].y>nodes[rs(rt)].ls)) { nodes[rt].x=nodes[ls(rt)].rs; nodes[rt].y=nodes[rs(rt)].ls; nodes[rt].mx=vv; } }}void build(int rt, int l, int r){ nodes[rt].l=l; nodes[rt].r=r; if(l==r) { nodes[rt].ls=nodes[rt].rs=nodes[rt].x=nodes[rt].y=l; nodes[rt].mx=a[l]; return; } int mid=(l+r)/2; build(ls(rt),l,mid); build(rs(rt),mid+1,r); pushup(rt);}Node query(int rt, int l, int r){ if(nodes[rt].l == l && nodes[rt].r == r) { return nodes[rt]; } int mid=(nodes[rt].l+nodes[rt].r)/2; if(r<=mid)return query(ls(rt),l,r); else { if(l>mid) return query(rs(rt),l,r); else { Node a,b,ans; a=query(ls(rt),l,mid); b=query(rs(rt),mid+1,r); ans.l=a.l,ans.r=b.r; ///he bing if(cal(a.ls,a.l) >= cal(b.ls, a.l)) ans.ls=a.ls; else ans.ls=b.ls; if(cal(b.r,a.rs)>=cal(b.r,b.rs)) ans.rs=a.rs; else ans.rs=b.rs; ll vl=a.mx; ll vr=b.mx; ll vv=cal(b.ls,a.rs); if(vl >=vr) { ans.mx=vl; ans.x=a.x; ans.y=a.y; } else { ans.mx=vr; ans.x=b.x; ans.y=b.y; } bool flag=0; if(ans.mx<vv) flag=1; else { if(ans.mx==vv) { if(a.rs<ans.x) flag=1; if(a.rs==ans.x && ans.y>b.ls) flag=1; } } if(flag) { ans.mx=vv; ans.x=a.rs; ans.y=b.ls; } return ans; } }}int main(){ //IN("la3938.txt"); int n,m,ic=0,l,r; Node ans; while(~scanf("%d%d",&n,&m)) { sum[0]=0; for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); sum[i]=sum[i-1]+a[i]; } build(1,1,n); printf("Case %d:\n",++ic); while(m--) { scanf("%d%d",&l,&r); ans=query(1,l,r); printf("%d %d\n",ans.x,ans.y); } } return 0;}