int solution(int A[], int N) {
if (N==0) return -1;
int i=0;
long long lsum=0;
long long rsum=0;
for (i=1;i<N;i++) rsum+=A[i];
if (rsum==0) return 0;
for (i=1;i<N;i++){
rsum -= A[i];
lsum += A[i-1];
if (lsum==rsum) return i;
}
return -1;
}int solution(int N) {
int pos;
int max=0;
int curr=-1;
for(pos=0;pos<sizeof(int)*8;pos++){
if ( ( N & ( 1 << pos ) ) != 0 ){
if (curr>max) max=curr;
curr=0;
}else{
if (curr!=-1) curr++;
}
}
return max;
}struct Results solution(int A[], int N, int K) {
struct Results result;
result.A = A;
result.N = N;
if ((N<2)||(K==0)||(A==0)) return result;
int i;
int temp;
for(;K>0;K--){
temp=A[N-1];
for(i=N-1;i>0;i--){
A[i]=A[i-1];
}
A[0]=temp;
}
return result;
}int solution(int A[], int N) {
int i=0;
int result=0;
for (i=0;i<N;i++) result ^= A[i];
return result;
}int solution(int X, int Y, int D) {
if ((Y-X)%D==0) return ((Y-X)/D);
return ((Y-X)/D)+1;
}int solution(int A[], int N) {
if (N==0) return 1;
int f[N+1];
int i=0;
for (i=0;i<N+1;i++){
f[i]=0;
}
for (i=0;i<N;i++){
f[A[i]-1]=1;
}
for (i=0;i<N+1;i++){
if (f[i]==0) return (i+1);
}
return N+1;
}int solution(int A[], int N) {
int right=0;
int i;
for (i=1;i<N;i++){
right += A[i];
}
int left=A[0];
int min=abs(left-right);
for (i=1;i<N-1;i++){
left += A[i];
right -= A[i];
if (abs(left-right)<min){
min=abs(left-right);
}
}
return min;
}int solution(int A[], int N) {
int f[N];
int i=0;
for (i=0;i<N;i++){
f[i]=0;
}
for (i=0;i<N;i++){
if (((A[i]-1)<N)&&(A[i]-1>=0)) f[A[i]-1]=1;
}
for (i=0;i<N;i++){
if (f[i]==0) return i+1;
}
return N+1;
}int solution(int A[], int N) {
int i;
int count[N];
for(i=0;i<N;i++) count[i]=0;
for(i=0;i<N;i++){
if (A[i]>N) return 0;
if (count[A[i]-1]>0) return 0;
count[A[i]-1]++;
}
for(i=0;i<N;i++){
if (count[i]==0) return 0;
}
return 1;
}int solution(int X, int A[], int N) {
int i;
int count[X];
for(i=0;i<X;i++) count[i]=0;
int full=0;
for(i=0;i<N;i++){
if (count[A[i]-1]==0){
count[A[i]-1]=1;
full++;
if (full==X) return i;
}
}
return -1;
}#include <strings.h>
struct Results solution(int N, int A[], int M)
{
struct Results result;
result.C = (int*)malloc(sizeof(int)*N);
bzero(result.C,sizeof(int)*N);
result.L = N;
int i;
int max=0; int lastappliedmax=0;
for(i=0;i<M;i++) {
if (A[i]<=N) {
if (result.C[A[i]-1]<=lastappliedmax) { result.C[A[i]-1] = lastappliedmax+1;
}else{ result.C[A[i]-1]++;
} if (result.C[A[i]-1]>max) {
max=result.C[A[i]-1];
}
}else{ lastappliedmax=max;
}
}
for(i=0;i<N;i++){
if (result.C[i]<lastappliedmax) result.C[i]=lastappliedmax;
}
return result;
}int solution(int A[], int N) {
int i;
int zeroes=0;
int count=0;
for (i=0;i<N;i++){
if (A[i]==0) zeroes++;
else if (count+zeroes<=1000000000){
count+=zeroes;
}else{
return -1;
}
}
return count;
}int solution(int A, int B, int K) {
if (A%K == 0) return ( B/K - A/K + 1 );
return ( B/K - A/K );
}int solution(int A[], int N) {
int p[N+1];
p[0]=0;
p[1]=A[0];
p[2]=p[1]+A[1];
double minavg = p[2]/2;
int minindex=0;
for(int i=3;i<=N;i++){
p[i]=p[i-1]+A[i-1];
if ( ((p[i]-p[i-2])/2.0) < minavg ){
minindex=i-2;
minavg=(p[i]-p[i-2])/2.0;
}
if ( ((p[i]-p[i-3])/3.0) < minavg ){
minindex=i-3;
minavg=(p[i]-p[i-3])/3.0;
}
}
return minindex;
}#include <strings.h>
#include <strings.h>
struct Results solution(char *S, int P[], int Q[], int M) {
struct Results result;
result.A = (int*)(malloc(sizeof(int)*M));
result.M = M;
int i;
int N=strlen(S);
int count[N][4];
int t[4]={0,0,0,0};
bzero(count,sizeof(int)*N*4);
for (i=0;i<N;i++){
switch (*(S+i)){
case 'A':
t[0]++;
break;
case 'C':
t[1]++;
break;
case 'G':
t[2]++;
break;
case 'T':
t[3]++;
break;
}
count[i][0]=t[0];
count[i][1]=t[1];
count[i][2]=t[2];
count[i][3]=t[3];
}
int c;
int cur;
for (i=0;i<M;i++){
result.A[i]=4;
for(c=2;c>=0;c--){
cur=count[Q[i]][c];
if (P[i]>0) cur -= count[P[i]-1][c];
if (cur>0) result.A[i]=c+1;
}
}
return result;
}void merge(int *a, int *b, int lo, int mid, int hi)
{
int k;
int i = lo, j = mid+1;
for (k = lo; k <= hi; k++) {
if (i > mid) b[k] = a[j++];
else if (j > hi) b[k] = a[i++];
else if ((a[j] < a[i])) b[k] = a[j++];
else b[k] = a[i++];
}
}
void sort(int *a, int *b, int lo, int hi)
{
if (hi <= lo) return;
int mid = lo + (hi - lo) / 2;
sort(b, a, lo, mid);
sort(b, a, mid+1, hi);
merge(a, b, lo, mid, hi);
}
int solution(int A[], int N)
{
if (N==0) return 0;
int i;
int b[N];
for (i=0;i<N;i++) b[i]=A[i];
sort(A,b,0,N-1);
int count=1;
for (i=1;i<N;i++) if (b[i]!=b[i-1]) count++;
return count;
}void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void partial_sort_higher_n(int* a, int size, int count)
{
int i, j;
for(j=1;j<count+1;j++){
for(i=0;i<size-j;i++){
if (a[i]>a[size-j]){
swap(a+i,a+size-j);
}
}
}
}
void partial_sort_lower_n(int* a, int size, int count)
{
int i, j;
for(j=0;j<count;j++){
for(i=j;i<size;i++){
if (a[i]<a[j]){
swap(a+i,a+j);
}
}
}
}
int solution(int A[], int N) {
if (N==3) return (A[0]*A[1]*A[2]);
partial_sort_higher_n(A, N, 3);
partial_sort_lower_n(A, N, 2);
int r1=A[N-1]*A[N-2]*A[N-3];
int r2=A[N-1]*A[0]*A[1]; return (r1>r2?r1:r2);
}int cmpfunc(const void * a, const void * b)
{
int A=*(int*)a;
int B=*(int*)b;
if (A>B) return 1;
else if (A<B) return -1;
return 0;
}
int solution(int A[], int N)
{
if (N<3) return 0;
qsort(A, N, sizeof(int), cmpfunc);
int i;
for (i=0;i<N-2;i++){ if ((long long)A[i]+(long long)A[i+1]>(long long)A[i+2]) return 1;
}
return 0;
}int cmpfunc(const void * a, const void * b)
{
long long A=*(long long*)a;
long long B=*(long long*)b;
if (A>B) return 1;
else if (A<B) return -1;
return 0;
}
int solution(int A[], int N)
{
long long low[N]; long long hig[N];
int i;
for (i=0;i<N;i++){
low[i]=(long long)i-A[i];
hig[i]=(long long)i+A[i];
}
qsort(low, N, sizeof(long long), cmpfunc);
qsort(hig, N, sizeof(long long), cmpfunc);
int ret=0; int scount=1; int j=0;
for(i=1;i<N;i++){
while((j<N)&&(low[i]>hig[j])){ j++;
scount--;
}
ret += scount;
if (ret>10000000) return -1;
scount++;
}
return ret;
}int solution(char *S)
{ char *stack=malloc(sizeof(char)*strlen(S));
char *ps=stack;
char *p=S;
while(*p!=0){
switch (*p){
case '(':
case '[':
case '{':
*ps=*p;
ps++;
break;
case '}':
if (*(ps-1)!='{') return 0;
ps--;
break;
case ']':
if (*(ps-1)!='[') return 0;
ps--;
break;
case ')':
if (*(ps-1)!='(') return 0;
ps--;
break;
}
p++;
}
if (ps!=stack) return 0;
return 1;
}#define CAPACITY 100000
int stack[CAPACITY];
int top = -1;
int isempty()
{
if (top == -1) return 1;
else return 0;
}
int isfull()
{
if (top == CAPACITY) return 1;
else return 0;
}
int pop()
{
int data=0;
if (!isempty()) {
data = stack[top];
top--;
}
return data;
}
void push(int data)
{
if (!isfull()) {
top++;
stack[top] = data;
}
}
int solution(int H[], int N) {
int count=0;
int i;
int found=0;
for (i=0;i<N;i++){
found=0;
while(!isempty()){
if (stack[top]<H[i]) break;
else if (stack[top]>H[i]) pop();
else if (stack[top]==H[i]){
found=1;
pop();
break;
}
}
push(H[i]);
if (!found) count++;
}
return count;
}int solution(char *S)
{
int count=0;
while(*S!=0){
if (*S=='(') count++;
else count--;
if (count<0) return 0;
S++;
}
return (count==0?1:0);
}int capacity;
int *stack;
int top = -1;
int isempty()
{
if (top == -1) return 1;
else return 0;
}
int isfull()
{
if (top == capacity) return 1;
else return 0;
}
int pop()
{
int data=0;
if (!isempty()) {
data = stack[top];
top--;
}
return data;
}
void push(int data)
{
if (!isfull()) {
top++;
stack[top] = data;
}
}
int solution(int A[], int B[], int N) {
int count=0;
int i=0;
stack = malloc(sizeof(int)*N);
capacity=N;
while(i<N){
if (B[i]==1){
push(A[i]);
i++;
}else{
while((!isempty())&&(i<N)){
if (stack[top]<A[i]) pop();
else{
i++;
break;
}
}
if (isempty()){
count++;
i++;
}
}
}
return (count+top+1);
}int solution(int A[], int N)
{
if (N==0) return -1;
if (N==1) return A[0];
int k;
int stacksize=0;
int value;
for(k=0;k<N;k++){
if (stacksize==0){
stacksize++;
value=A[k];
}else if(value!=A[k]){
stacksize--;
}else{
stacksize++;
}
}
if (stacksize<=0) return -1;
int count=0;
int index=-1;
for(k=0;k<N;k++){
if (A[k]==value){
count++;
index=k;
}
}
if (count>N/2) return index;
return -1;
}int solution(int a[], int size) {
if (size==1) return 0;
int k;
int stacksize=0;
int value;
for(k=0;k<size;k++){
if (stacksize==0){
stacksize++;
value=a[k];
}else if(value!=a[k]){
stacksize--;
}else{
stacksize++;
}
}
if (stacksize<=0) return 0;
int count=0;
for(k=0;k<size;k++){
if (a[k]==value) count++;
}
if (count<=size/2) return 0;
int pcount=0;
int ret=0;
for(k=0;k<size;k++){
if (a[k]==value) pcount++;
if ((pcount>(k+1)/2.0)&&(count-pcount>(size-k-1)/2.0)) ret++;
}
return ret;
}int solution(int A[], int N) {
if (N<=1) return 0;
int a[N-1];
int k;
for(k=0;k<N-1;k++){
a[k]=A[k+1]-A[k];
}
int max_ending=0;
int max_slice=0;
for(k=0;k<N-1;k++){
max_ending=((0>(max_ending+a[k]))?0:(max_ending+a[k]));
if (max_ending>max_slice) max_slice=max_ending;
}
return max_slice;
}int solution(int A[], int N) {
int max_ending=0;
int max_slice=0;
int k;
for(k=0;k<N;k++){
max_ending=((0>(max_ending+A[k]))?0:(max_ending+A[k]));
if (max_ending>max_slice) max_slice=max_ending;
}
if (max_slice==0){
max_slice=A[0];
for(k=0;k<N;k++){
if (A[k]>max_slice) max_slice=A[k];
}
}
return max_slice;
}int solution(int A[], int N) {
int k;
int max_until[N];
max_until[0]=0;
max_until[1]=0;
for(k=2;k<N;k++){
max_until[k]=((0>(max_until[k-1]+A[k-1]))?0:(max_until[k-1]+A[k-1]));
}
int max_from[N];
max_from[N-1]=0;
max_from[N-2]=0;
for(k=N-3;k>=0;k--){
max_from[k]=((0>(max_from[k+1]+A[k+1]))?0:(max_from[k+1]+A[k+1]));
}
int max_double=0;
for(k=1;k<N-1;k++){
if (max_until[k]+max_from[k]>max_double) max_double=max_until[k]+max_from[k];
}
return max_double;
}int solution(int N) {
int i=1;
int count=0;
while(((long long)i*i)<N){
if (N%i==0) count+=2;
i++;
}
if ((long long)i*i==N) count++;
return count;
}int solution(int N) {
int i=1;
int min=2*(N+1);
while(((long long)i*i)<N){
if (N%i==0){
if (2*(i+N/i)<min) min=2*(i+N/i);
}
i++;
}
if ((long long)i*i==N){
if ((4*i)<min) min=4*i;
}
return min;
}int solution(int A[], int N) {
if (N<3) return 0;
int k;
int pcount=0;
int peak[N/2];
for(k=1;k<N-1;k++){
if ((A[k-1]<A[k])&&(A[k+1]<A[k])){
peak[pcount]=k;
pcount++;
}
}
if (pcount<3) return pcount;
int max=2;
int count;
int p;
int flag;
for(k=2;k<=pcount;k++){
count=1;
flag=0;
for(p=1;(p<pcount)&&(count<k);p++){
if (peak[p]-peak[flag]>=k){
count++;
flag=p;
}
}
if (count>max) max=count;
else if (count<max) break;
}
return max;
}int solution(int A[], int N)
{
int k;
int pcount=0;
int peaks[N];
peaks[0]=0;
for(k=1;k<N-1;k++){
if ((A[k-1]<A[k])&&(A[k+1]<A[k])){
pcount++;
}
peaks[k]=pcount;
}
peaks[N-1]=pcount;
if (pcount<1) return 0;
if (pcount==1) return 1;
int blockcount;
int blocksize;
int p;
int prevcount;
int found=0;
for (blockcount=pcount;(blockcount>0)&&(found==0);blockcount--){
if (N%blockcount!=0) continue;
blocksize=N/blockcount;
prevcount=0;
found=1;
for(p=blocksize-1;(p<N)&&(found==1);p+=blocksize){
if (peaks[p]<=prevcount) found=0;
prevcount=peaks[p];
}
}
return blockcount+1;
}#include <string.h>
struct Results solution(int n, int P[], int Q[], int M) {
struct Results result;
int F[n];
memset(F,0,sizeof(int)*n); int i=2;
int k;
while(i*i<=n){
if (F[i-1]==0){
k=i*i;
while(k<=n){
if (F[k-1]==0) F[k-1]=i;
k += i;
}
}
i++;
}
int semiprimesacc[n];
int num;
int primefactcount;
int sempiprimestot=0;
for(k=0;k<n;k++){
num=k+1; primefactcount=1;
while(F[num-1]>0){
primefactcount++;
num/=F[num-1];
}
if (primefactcount==2) sempiprimestot++;
semiprimesacc[k]=sempiprimestot;
}
result.A = (int*)malloc(sizeof(int)*M);
result.M = M;
for(k=0;k<M;k++){
result.A[k]=semiprimesacc[Q[k]-1]-semiprimesacc[P[k]-2];
}
return result;
}struct Results solution(int A[], int N) {
int k;
struct Results result;
int max=0;
for(k=0;k<N;k++){
if (A[k]>max) max=A[k];
} int dcount[max];
for(k=0;k<max;k++) dcount[k]=N; int n;
for(k=0;k<N;k++){
for(n=A[k];n<=max;n+=A[k]){
if (dcount[n-1]>0) dcount[n-1]--;
}
}
result.C = (int*)malloc(sizeof(int)*N);
result.L = N; for(k=0;k<N;k++){
result.C[k]=dcount[A[k]-1];
}
return result;
}long long gcd(long long a, long long b)
{
if (a%b==0) return b;
return gcd(b,a%b);
}
long long lcm(long long a,long long b)
{
return (a*b)/gcd(a,b);
}
int solution(int N, int M)
{
if (N==0) return 0;
if (M==0) return 1;
return lcm(N,M)/M;
}int gcd(int a, int b)
{
if ((a==0)||(b==0)) return 0;
if (a%b==0) return abs(b);
return gcd(b,a%b);
}
int same_prime_factors(int a, int b)
{
int init_gcd=gcd(a,b);
int aux_gcd=init_gcd;
while (aux_gcd != 1){
a /= aux_gcd;
aux_gcd = gcd(a, aux_gcd);
}
if (a != 1) return 0;
aux_gcd = init_gcd;
while (aux_gcd != 1){
b /= aux_gcd;
aux_gcd = gcd(b, aux_gcd);
}
if (b != 1) return 0;
return 1;
}
int solution(int A[], int B[], int Z)
{
int k;
int count=0;
for (k=0;k<Z;k++){
count += same_prime_factors(A[k],B[k]);
}
return count;
}typedef unsigned long long ull;
struct Results solution(int A[], int B[], int L) {
ull k;
ull fib[L+1];
fib[0]=0;
fib[1]=1; for(k=2;k<L+2;k++){
fib[k]=fib[k-1]+fib[k-2];
}
struct Results result;
result.C=(int*)malloc(sizeof(int)*L);
result.L=L;
int mod;
for (k=0;k<L;k++){
mod=1<<B[k]; result.C[k]=fib[A[k]+1]%mod;
}
return result;
}#include <alloca.h>
#include <memory.h>
#include <limits.h>
int solution(int A[], int N)
{ if (N <= 2) return 1; int* reached = (int*)alloca(sizeof(int) * N);
memset(reached, 0x00, sizeof(int) * N); reached[0] = A[0];
reached[1] = A[1]; int* fibN = (int*)alloca(26 * sizeof(int));
fibN[0] = 0;
fibN[1] = 1;
int i = 2;
while (i < 26){
fibN[i] = fibN[i - 1] + fibN[i - 2]; if (fibN[i] == N+1) return 1; if (fibN[i] - 1 < N && A[fibN[i] - 1] == 1) reached[fibN[i] - 1] = 1;
i++;
} int min = INT_MAX;
for (i = 0; i < N; i++){ if (reached[i] == 0) continue;
int min_jumps_to_here = reached[i];
int j;
for (j = 2; j < 26; j++){
int next_pos = i + fibN[j]; if (next_pos == N){
min = min_jumps_to_here + 1 < min ? min_jumps_to_here + 1 : min;
break;
} if (next_pos > N || A[next_pos] == 0) continue; if (reached[next_pos] == 0 || reached[next_pos] > min_jumps_to_here + 1){
reached[next_pos] = min_jumps_to_here + 1;
}
}
}
if (min!=INT_MAX) return min;
return -1;
}int solution(int A[], int B[], int N, int C[], int M) { int nail_acc[2*M+2]; int nail_acc_psum[2*M+2]; int nhig=M-1;
int nlow=0;
int nmid; int ncountmin=-1;
int i;
int count;
while(nlow<=nhig){ nmid=(nhig+nlow)/2;; for (i=0;i<2*M+2;i++) nail_acc[i]=0;
for (i=0;i<=nmid;i++) nail_acc[C[i]]++; nail_acc_psum[0]=nail_acc[0];
for (i=1;i<2*M+2;i++) nail_acc_psum[i]=nail_acc_psum[i-1]+nail_acc[i]; count=0;
for (i=0;i<N;i++){
if (nail_acc_psum[B[i]]-nail_acc_psum[A[i]-1]>0){
count++;
}
}
if (count==N){
ncountmin=nmid+1;
nhig=nmid-1;
}else{
nlow=nmid+1;
}
}
return ncountmin;
}int test_subarray(int A[], int size, int maxslicecount, int maxslicesum)
{
int i;
int sum=0;
int slicecount=1;
for (i=0; i<size; i++){
if (A[i]>maxslicesum) return 0;
sum += A[i];
if (sum > maxslicesum){
slicecount++;
if (slicecount>maxslicecount) return 0;
sum = A[i];
}
}
if (slicecount>maxslicecount) return 0;
return 1;
}
int solution(int K, int M, int A[], int N) {
int i;
int min=0;
int max=0;
int med;
for (i=0;i<N;i++) max+=A[i];
int res=max;
while(min<=max){
med=(min+max)/2;
if (test_subarray(A, N, K, med)==1){
if (med<res) res=med;
max=med-1;
}else{
min=med+1;
}
}
return res;
}int solution(int M, int A[], int N) {
unsigned long long count=0;
int acc[M+1];
int i;
for(i=0;i<M+1;i++) acc[i]=-1;
int front=0;
int back=0;
while(front<N){
if (acc[A[front]]>=back){
back=acc[A[front]]+1;
}else{
acc[A[front]]=front;
count+=front-back+1;
if (count>1000000000) return 1000000000;
front++;
}
}
return count;
}int solution(int A[], int N) {
if (N==1) return 1;
int count=1;
if (A[0]>=0 || A[N-1]<=0){
int i;
for (i=1;i<N;i++){
if (A[i]!=A[i-1]) count++;
}
return count;
}
int beg=0;
int end=N-1;
unsigned int ab,ae;
while(beg!=end){
ab=abs(A[beg]);
ae=abs(A[end]);
if (ab!=ae) count++;
if (ab>ae && A[beg+1]<=0){
beg++;
while(A[beg]==A[beg-1] && A[beg+1]<=0) beg++;
}else if (ab<ae && A[end-1]>=0){;
end--;
while(A[end]==A[end+1] && A[end-1]>=0) end--;
}else{
if (A[beg+1]<=0) beg++;
else if (A[end-1]>=0) end--;
else return count;
}
}
return count;
}int cmpfunc(const void * a, const void * b)
{
int A=*(int*)a;
int B=*(int*)b;
if (A>B) return 1;
else if (A<B) return -1;
return 0;
}
int solution(int A[], int N)
{
if (N<3) return 0;
qsort(A, N, sizeof(int), cmpfunc);
int count=0;
int x,y,z;
for(x=0; x<N; x++){
z=x+2;
for(y=x+1; y<N; y++){
while((z<N) && ((A[x]+A[y])>A[z])){
z++;
}
count+=z-y-1;
}
}
return count;
}int cmpfunc(const void * a, const void * b)
{
int A=*(int*)a;
int B=*(int*)b;
if (A>B) return 1;
else if (A<B) return -1;
return 0;
}
int solution(int A[], int N) {
int min=abs(A[0]+A[0]);
if (N==1) return min;
qsort(A, N, sizeof(int), cmpfunc);
int end=0;
while (end<N && A[end]<0) end++;
if (end==0) return 2*A[0];
if (end==N) return -2*A[N-1];
int beg=end-1;
int curr;
while ( beg>=0 && end<N ){
curr=abs(A[beg]+A[end]);
if (curr<min) min=curr;
if (min==0) break;
if (A[end]+A[beg]<0) end++;
else beg--;
}
return min;
}int solution(int K, int A[], int N) {
int count=0;
unsigned int len=0;
int i;
for(i=0;i<N;i++){
len+=A[i];
if (len>=K){
count++;
len=0;
}
}
return count;
}int solution(int A[], int B[], int N) {
if (N<2) return N;
int count = 1;
int end = B[0];
int i;
for (i = 1; i < N; i++) {
if (A[i] > end) {
count++;
end = B[i];
}
}
return count;
}int solution(int A[], int N) {
int i=0;
int p;
int sum;
for (i=1;i<N;i++){
sum = A[i] + A[i-1];
for(p=2; p<=6 && i-p>=0;p++){
if (A[i]+A[i-p] > sum){
sum = A[i]+A[i-p];
}
}
A[i]=sum;
}
return A[N-1];
}int solution(int A[], int N) {
int i,j;
int max=0;
int sum=0;
for (i=0;i<N;i++){
A[i]=abs(A[i]);
if (A[i]>max) max=A[i];
sum += A[i];
}
int C[max+1];
for (i=0;i<max+1;i++) C[i]=0;
for (i=0;i<N;i++) C[A[i]]++;
int R[sum+1];
for(i=1;i<sum+1;i++) R[i]=-1;
R[0]=0;
for(i=1;i<max+1;i++){
if (C[i]>=0){
for(j=0;j<=sum;j++){
if (R[j]>=0) R[j]=C[i];
else if (j>=i && R[j-i]>0) R[j] = R[j-i]-1;
}
}
}
int upper=sum;
int half = sum/2.0+0.5;
for(i=0;i<half;i++){
if (R[half+i]>=0){
upper=half+i;
break;
}
}
return 2*upper-sum;
}