Minimum Sum
Time limit:16000/8000 MS (java/others) Memory limit:65536/32768 K (java/others)
Total submission (s): 3710 Accepted Submission (s): 852
Problem descriptionyou is given N positive integers, denoted as x0, X1 ... xN-1. Then give some intervals [L, R]. For each interval, you need to find a number x to make as small as possible!
Inputthe first line was an integer t (t <=), indicating the number of test cases. For each test case, an integer n (1 <= n <= 100,000) comes first. Then comes N positive integers x (1 <= x <= $, 000,000) in the next line. Finally, comes an integer q (1 <= q <= 100,000), indicting there is Q queries. Each query consists of integers l, r (0 <= l <= R < N), meaning the interval you should with.
Outputfor The k-th test case, first output ' case #k: ' In a separate line. Then output Q lines, each of which is the minimum value of. Output a blank line after every test case.
Sample Input
253 6 2 2 421 40 227 720 11 1
Sample Output
Case #1:64Case #2:00
Authorstandy
Source2010 acm-icpc multi-university Training Contest (4)--host by UESTC
Recommendzhengfeng | We have carefully selected several similar problems for you:3474 1828 1698 1540 1394
topic Meaning:there is a set of numbers that is a number within the interval l~r, making the Sigma value minimal.
Problem Solving Ideas:divides the tree to find the median ave, and when it is made, it saves the number of points in the left sub-tree with the lsum array.
The generation of the Lsum array is described as follows:
give me a chestnut:
When you solve ans, you can divide the median to the left and the median to the right and the median number.
You can see the notes in detail.
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #define N 100050using namespace Std;int Sorted[n]; Sorted array int toleft[30][n]; TOLEFT[I][J] Indicates how many number of layer I from 1 to K are divided into the left int tree[30][n]; A value that represents each position of each layer int n;//the number of inputs to a long long sum[n];//the sum of all the elements in the current position and before the long long lsum[30][n];//in the interval of the first element of the deep layer The sum of the elements of the left subtree is divided in front of I and long long tsum;//represents less than the median ave portion and void building (int l,int r,int dep) {if (l==r) return; int mid = (l+r) >>1; int temp = Sorted[mid]; int i,sum_same=mid-l+1;//represents equal to the median value and is divided into the left number for (i=l; i<=r; i++) if (tree[dep][i]<temp) sum_same-- ; int leftpos = l; int rightpos = mid+1; for (i=l; i<=r; i++) {if (tree[dep][i]<temp)//is smaller than the middle number, divided into the left {Tree[dep+1][leftpos++]=tree[d Ep][i]; Lsum[dep][i] = lsum[dep][i-1] + tree[dep][i];//record is divided to the left and how many} else if (tree[dep][i]==temp&&sum_same& gt;0)//equal to the median value, divided into the left, until sum==0 to the right {Tree[dep+1][leftpOs++]=tree[dep][i]; Lsum[dep][i] = Lsum[dep][i-1] + tree[dep][i]; sum_same--; } else//right {Tree[dep+1][rightpos++]=tree[dep][i]; Lsum[dep][i] = lsum[dep][i-1]; } Toleft[dep][i] = Toleft[dep][l-1] + leftpos-l; From 1 to I put the number on the left} building (l,mid,dep+1); Building (mid+1,r,dep+1);} Query interval k large number, [L,r] is a large interval, [l,r] is to query the inter-cell int query (int l,int r,int l,int r,int dep,int k) {if (l==r) return tree[dep][l]; int mid = (l+r) >>1; int cnt = Toleft[dep][r]-TOLEFT[DEP][L-1]; The number on the left of [l,r] if (cnt>=k) {int newl = L + toleft[dep][l-1]-toleft[dep][l-1];//l+ the number to be placed on the left before the interval to be queried int NEWR = NEWL + cnt-1; The left point plus the query interval will be placed in the number of return to query (L,MID,NEWL,NEWR,DEP+1,K); } else {int newr = R + (Toleft[dep][r]-toleft[dep][r]); int NEWL = NEWR-(r-l-cnt); tsum+=lsum[dep][r]-lsum[dep][l-1];//interval}}int main () {int t,cas=1; scanf ("%d", &t); While(t--) {scanf ("%d", &n); int i; for (I=1; i<=n; i++) {scanf ("%lld", &sorted[i]); Sum[i] = sum[i-1]+sorted[i];//Save includes the current position and all previous elements of the sum tree[0][i]=sorted[i]; } sort (sorted+1,sorted+1+n); Building (1,n,0); int l,r; int m;//Number of queries scanf ("%d", &m); printf ("Case #%d:\n", cas++); while (m--) {scanf ("%d%d", &l,&r); l++,r++; tsum=0;//represents the median ave portion and int k= (R-L)/2+1;//k is the median of interval ab long long ave= query (1,n,l,r,0,k);//ave is the value of the median, R -l+1-k is the number of left digits long long ans=sum[r]-sum[l-1]-ave* (r-l+1-k)-tsum-ave;//The median right and, greater than the AVE portion ans+= (k-1) *ave- tsum;//The median left and, smaller than the part of the Ave printf ("%lld\n", ans); } printf ("\ n"); } return 0;}
HDU 3473-minimum Sum (partition tree-find interval sigma minimum)