UvaLA 3938 "Ray, Pass me the dishes!"

                        "Ray, Pass me the dishes!"
Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

[]   [Go Back]   [Status]  

Description

Download as PDF
 

After doing Ray a great favor to collect sticks for Ray, Poor Neal becomes very hungry. In return for Neal's help, Ray makes a great dinner for Neal. When it is time for dinner, Ray arranges all the dishes he makes in a single line (actually this line is very long ... <tex2html_verbatim_mark>, the dishes are represented by 1, 2, 3 ... <tex2html_verbatim_mark>). ``You make me work hard and don't pay me! You refuse to teach me Latin Dance! Now it is time for you to serve me", Neal says to himself.

Every dish has its own value represented by an integer whose absolute value is less than 1,000,000,000. Before having dinner, Neal is wondering about the total value of the dishes he will eat. So he raises many questions about the values of dishes he would have.

For each question Neal asks, he will first write down an interval [ab] <tex2html_verbatim_mark>(inclusive) to represent all the dishes aa + 1,..., b <tex2html_verbatim_mark>, where a <tex2html_verbatim_mark>and b <tex2html_verbatim_mark>are positive integers, and then asks Ray which sequence of consecutive dishes in the interval has the most total value. Now Ray needs your help.

Input

The input file contains multiple test cases. For each test case, there are two integers n <tex2html_verbatim_mark>and m <tex2html_verbatim_mark>in the first line (nm < 500000) <tex2html_verbatim_mark>. n <tex2html_verbatim_mark>is the number of dishes and m <tex2html_verbatim_mark>is the number of questions Neal asks.

Then n <tex2html_verbatim_mark>numbers come in the second line, which are the values of the dishes from left to right. Next m <tex2html_verbatim_mark>lines are the questions and each line contains two numbers a <tex2html_verbatim_mark>, b <tex2html_verbatim_mark>as described above. Proceed to the end of the input file.

Output

For each test case, output m <tex2html_verbatim_mark>lines. Each line contains two numbers, indicating the beginning position and end position of the sequence. If there are multiple solutions, output the one with the smallest beginning position. If there are still multiple solutions then, just output the one with the smallest end position. Please output the result as in the Sample Output.

Sample Input

3 1 
1 2 3 
1 1

Sample Output

Case 1: 
1 1

[]   [Go Back]   [Status]  

也叫UVA 1400.。。。。
给一个区间{a,b},求区间内最大的连续和的范围  i,j
非常麻烦的线段树,调了好长时间。。。。。
每个节点维护,最大前缀和的位置pref,最大后缀和的位置suff,以及最大连续和的区间范围sub。。。。
 向上更新的时候,sub={两个子结点的sub,两个子结点交接处的和}
                            pref={左子结点的pref,延续到右子结点pref的和}   suff也一样
查询的时候,i,j可能是子结点的sub,也可能是左右结点并出来的值。。。 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 
  5 using namespace std;
  6 
  7 #define lson l,m,rt<<1
  8 #define rson m+1,r,rt<<1|1
  9 
 10 typedef long long int LL;
 11 typedef pair<int,int> Interval;
 12 const int maxn=500050;
 13 
 14 LL pref_sum[maxn];
 15 LL sum(int a,int b){return pref_sum[b]-pref_sum[a-1];}
 16 LL sum(Interval i){return sum(i.first,i.second);}
 17 
 18 Interval better(Interval a,Interval b)
 19 {
 20     LL A=sum(a),B=sum(b);
 21     if(A==B)
 22     {
 23         if(a<b) return a; else return b;
 24     }
 25     else if(A>B) return a;
 26     else if(A<B) return b;
 27 }
 28 
 29 struct IntervalTree
 30 {
 31     LL max_pref[maxn<<2],max_suff[maxn<<2];
 32     Interval max_sub[maxn<<2];
 33     ///pushUP  build   query_suff query_pref  query
 34     void pushUP(int l,int r,int rt)
 35     {
 36         ///sub
 37         int lc=rt<<1;
 38         int rc=rt<<1|1;
 39         max_sub[rt]=better(max_sub[lc],max_sub[rc]);
 40         max_sub[rt]=better(max_sub[rt],make_pair(max_suff[lc],max_pref[rc]));
 41 
 42         ///prex
 43         LL v1=sum(l,max_pref[lc]);
 44         LL v2=sum(l,max_pref[rc]);
 45         if(v1==v2)
 46             max_pref[rt]=max_pref[lc];
 47         else
 48             max_pref[rt]=v1>v2?max_pref[lc]:max_pref[rc];
 49 
 50         ///suffx
 51         v1=sum(max_suff[rc],r);
 52         v2=sum(max_suff[lc],r);
 53         if(v1==v2)
 54             max_suff[rt]=max_suff[lc];
 55         else
 56             max_suff[rt]=v1>v2?max_suff[rc]:max_suff[lc];
 57     }
 58     void build(int l,int r,int rt)
 59     {
 60         if(l==r)
 61         {
 62             max_suff[rt]=max_pref[rt]=l;
 63             max_sub[rt]=make_pair(l,l);
 64             return ;
 65         }
 66         int m=(l+r)>>1;
 67         build(lson);
 68         build(rson);
 69         pushUP(l,r,rt);
 70     }
 71     Interval query_pref(int L,int R,int l,int r,int rt)
 72     {
 73         if(max_pref[rt]<=R) return make_pair(L,max_pref[rt]);
 74         int m=(l+r)>>1;
 75         if(m>=R) return query_pref(L,R,lson);
 76         Interval i=query_pref(L,R,rson);
 77         i.first=L;
 78         return better(i,make_pair(L,max_pref[rt<<1]));
 79     }
 80     Interval query_suff(int L,int R,int l,int r,int rt)
 81     {
 82         if(max_suff[rt]>=L) return make_pair(max_suff[rt],R);
 83         int m=(l+r)>>1;
 84         if(m<L) return query_suff(L,R,rson);
 85         Interval i=query_suff(L,R,lson);
 86         i.second=R;
 87         return better(i,make_pair(max_suff[rt<<1|1],R));
 88     }
 89     Interval query(int L,int R,int l,int r,int rt)
 90     {
 91         if(L<=l&&r<=R) return max_sub[rt];
 92         int m=(l+r)>>1;
 93         if(R<=m) return query(L,R,lson);
 94         if(L>m) return query(L,R,rson);
 95         Interval i1=query_pref(L,R,rson);
 96         Interval i2=query_suff(L,R,lson);
 97         Interval i3=better(query(L,R,lson),query(L,R,rson));
 98         return better(i3,make_pair(i2.first,i1.second));
 99     }
100 };
101 
102 IntervalTree tree;
103 
104 int main()
105 {
106     int cas=1,a,b,n,m;
107     while(scanf("%d%d",&n,&m)!=EOF)
108     {
109         pref_sum[0]=0;
110         for(int i=1;i<=n;i++)
111         {
112             scanf("%d",&a);
113             pref_sum[i]=pref_sum[i-1]+a;
114         }
115         tree.build(1,n,1);
116         printf("Case %d:
",cas++);
117         while(m--)
118         {
119             scanf("%d%d",&a,&b);
120             Interval ans=tree.query(a,b,1,n,1);
121             printf("%d %d
",ans.first,ans.second);
122         }
123     }
124     return 0;
125 }
原文地址:https://www.cnblogs.com/CKboss/p/3414744.html