Sicily 1136 (segment tree + maximum sub-array)

Source: Internet
Author: User

title link:Sicily 1136

Problem Solving Ideas:
The maximum number of sub-arrays within a range is required, and access may be frequent and time complexity needs to reach O (n*logn), so it is natural to think of the line segment tree . We can use the line segment tree to save the maximum sub-array of the interval, but think about it again is not right, if the access to the interval across the two cells how to break, so, this is not just a simple interval of continuous and the problem, but also a little bit of skill.
How do you get the maximum subarray, remember that the introduction to the algorithm introduces a method of using divide and conquer method to find the maximal sub-array (the largest sub-array of divide-and-conquer method)?
Let's say we ask for the maximum sub-array of the interval [low, high], and the various information about [low, mid] and [Mid+1, High] (mid is the midpoint of the interval, the various information here is not determined), how do we get the largest subarray? Then there is the formula:
Root->max_sum=max (Root->l->max_sum, Root->r->max_sum, Root->l->lmax+root->r->rmax)
The Lmax here represents the maximum continuity of the right boundary of the interval, and the Rmax is the largest continuous with the left boundary, and because the topic ultimately needs to find the interval, the boundaries of each seed array need to be recorded, the following is the definition of the segment tree structure:

struct  node{int  left,right,sum;    //interval left and right boundary, interval and  long        long  Lmax,rmax;    //contains the maximum contiguous and  of the right and left boundaries.       int  l_index,r_index;    //lmax left boundary, Rmax right boundary  long          long  max_sum;    //maximum continuous and      int  left_bound,right_bound;    //the largest continuous and left and right boundary  node *l,*r; Node (int  l,int  R): Left (L), right (R), L (null ), R (null ) {}};  

Then Lmax and Rmax also have the formula:
Root->lmax=max (Root->r->lmax, Root->l->lmax+root->r->sum)
Root->rmax=max (Root->l->rmax, Root->r->rmax+root->l->sum)
Finally there is a detail, the answer of the interval [I, J] I, J is the smallest, there is no big problem!

AC Code:

#include <bits/stdc++.h>usingnamespace Std;intn,a[100005];structnode{int left,right,sum;    Long Long Lmax,rmax;    int l_index,r_index;    Long Long max_sum;    int left_bound,right_bound;    Node *l,*r; Node (int l,int R): Left (L), right (R), L (NULL), R (NULL){}};voidPUSH_UP (node* root) {root->sum=root->l->sum+root->r->sum;    root->lmax=root->r->lmax,root->l_index=root->r->l_index; From mid to leftif(Root->l->lmax+root->r->sum >= Root->lmax)        {root->lmax=root->l->lmax+root->r->sum;    root->l_index=root->l->l_index;    } root->rmax=root->l->rmax,root->r_index=root->l->r_index; From mid to rightif(Root->r->rmax+root->l->sum > Root->rmax)        {root->rmax=root->r->rmax+root->l->sum;    root->r_index=root->r->r_index;                 } root->max_sum=root->l->max_sum;           Max Sum root->left_bound=root->l->left_bound; root->right_bound=root->l->right_bound;if(Root->l->lmax+root->r->rmax > Root->max_sum)        {root->max_sum=root->l->lmax+root->r->rmax;        root->left_bound=root->l->l_index;    root->right_bound=root->r->r_index; }if(Root->r->max_sum > Root->max_sum)        {root->max_sum=root->r->max_sum;        root->left_bound=root->r->left_bound;    root->right_bound=root->r->right_bound; }}voidCreate (node* root) {int l=root->left,r=root->right;if(L<r) {int mid= (L+R) >>1;        Root->l=new node (l,mid); Root->r=new Node (mid+1, R);        Create (ROOT-&GT;L);        Create (ROOT-&GT;R);    Push_up (root); }Else{root->sum=a[l];        root->lmax=root->rmax=root->sum;        Root->left_bound=root->right_bound= root->l_index=root->r_index=l;            root->max_sum=root->sum; }}nodeQuery (node* root,int l,int R) {if(root->left==l&&root->right==r) return *root; int mid= (root->left + root->right)/2;if(mid>=r) return query (ROOT-&GT;L,L,R);Else if(L&GT;MID) return query (ROOT-&GT;R,L,R);Else{node Ans_l=query (root->l,l,mid), Ans_r=query (root->r,mid+1, R);        Node ans (l,r);        Ans.sum=ans_l.sum+ans_r.sum;      Ans.lmax=ans_r.lmax,ans.l_index=ans_r.l_index; From mid to leftif(Ans_l.lmax+ans_r.sum >= Ans.lmax) Ans.lmax=ans_l.lmax+ans_r.sum,ans.l_index=ans_l.l_index;      Ans.rmax=ans_l.rmax,ans.r_index=ans_l.r_index; From mid to rightif(Ans_r.rmax+ans_l.sum > Ans.rmax) ans.rmax=ans_r.rmax+ans_l.sum,ans.r_index=ans_r.r_index; Ans.max_sum=ans_l.max_sum,//max sum Ans.left_bound=ans_l.left_bound, a Ns.right_bound=ans_l.right_bound;if(Ans_l.lmax+ans_r.rmax > Ans.max_sum)            {Ans.max_sum=ans_l.lmax+ans_r.rmax;        Ans.left_bound=ans_l.l_index,ans.right_bound=ans_r.r_index; }if(Ans_r.max_sum > Ans.max_sum) ans.max_sum=ans_r.max_sum, Ans.left_bound=ans_r.left_bound,        Ans.right_bound=ans_r.right_bound;    return ans; } }voidPrint (node* root)//test with {printf ("l:%d r:%d sum:%d\n", root->left,root->right,root->sum); printf"mid_to_left:%d:%d\n", Root->l_index,root->lmax); printf"mid_to_right:%d:%d\n", Root->r_index,root->rmax); printf"max:l:%d r:%d sum:%d\n\n", root->left_bound,root->right_bound,root->max_sum);if(root->l) print (root->l);if(root->r) print (root->r);}intMain () {int n,m; scanf"%d%d", &n,&m); for (int i=1; i<=n;i++) scanf ("%d", &a[i]); node* root=new Node (1, n);    Create (root);//print (root);    int x, y; while (m--){scanf ("%d%d", &x,&y);        Node Tmp=query (root,x,y); printf"%d%d%lld\n", tmp.left_bound,tmp.right_bound,tmp.max_sum); } return0;}

Summary:
1, Segment tree is really a good thing, with the interval-related queries, consider it more;
2, the method of splitting and administering the maximum subarray is also very important;
3, pay attention to details, do not hand cheap!!!

Sicily 1136 (segment tree + maximum sub-array)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.