Editorial for Phân tập
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của flashmt
const fi=''; fo=''; maxs=65536; max=16000000; type ar=array[0..maxs] of longint; var n,m,m1,m2,i,j,k,sum,t,num,q,rem,temp,re:longint; dem:int64; a:array[0..31] of longint; b:array[0..15] of longint; p:array[0..16] of longint; f,g,sl:ar; tr:array[0..max] of longint; npos:longint; procedure rf; var i:longint; begin assign(input,fi); reset(input); p[0]:=1; for i:=1 to 16 do p[i]:=p[i-1] shl 1; readln(n); m:=n div 2-1; m1:=p[m+1]-1; sum:=0; for i:=0 to m do begin read(a[i]); sum:=sum+a[i]; end; m:=n-n div 2-1; for i:=0 to m do begin read(b[i]); sum:=sum+b[i]; end; m2:=p[m+1]-1; close(input); end; procedure wf; begin assign(output,fo); rewrite(output); write(re,' ',dem); close(output); end; procedure sort(l,r:longint); var x,y,i,j:longint; begin i:=l; j:=r; x:=f[(i+j) div 2]; repeat while f[i]<x do i:=i+1; while f[j]>x do j:=j-1; if i<=j then begin y:=f[i]; f[i]:=f[j]; f[j]:=y; i:=i+1; j:=j-1; end; until i>j; if i<r then sort(i,r); if l<j then sort(l,j); end; function bs(x:longint;var num:longint):longint; var l,r,m,y,re,t,u,i:longint; begin l:=1; r:=npos; num:=0; y:=-1; re:=maxlongint; bs:=re; while l<=r do begin m:=(l+r) shr 1; if f[m]=x then break; if f[m]<x then l:=m+1 else r:=m-1; end; if rem=0 then begin for i:=m-1 to m+1 do if (i>0) and (i<=npos) and (abs(f[i]-x)<re) then begin re:=abs(f[i]-x); y:=f[i]; end; if y<>-1 then begin bs:=re*2; t:=tr[y]; num:=sl[t]; if re<>0 then begin if (2*x-y<0) or (2*x-y>max) then exit; t:=tr[2*x-y]; if t>0 then num:=num+sl[t]; end; end; end else begin for i:=m-2 to m+2 do if (i>0) and (i<=npos) then begin if f[i]<=x then begin if x-f[i]<re then begin re:=abs(f[i]-x); y:=f[i]; end; end else begin if f[i]-1-x<re then begin re:=f[i]-x-1; y:=f[i]; end; end; end; if y<>-1 then begin bs:=2*re+1; t:=tr[y]; num:=num+sl[t]; if (2*x+1-y<0) or (2*x-y+1>max) then exit; t:=tr[2*x+1-y]; if t>0 then num:=num+sl[t]; end; end; end; begin rf; for i:=1 to m1 do begin k:=i; j:=0; while k>0 do begin if k and 1=1 then f[i]:=f[i]+a[j]; j:=j+1; k:=k shr 1; end; end; sort(0,m1); g:=f; npos:=1; fillchar(f,sizeof(f),0); f[1]:=0; tr[0]:=1; sl[1]:=1; for i:=1 to m1 do if g[i]=g[i-1] then inc(sl[npos]) else begin inc(npos); f[npos]:=g[i]; tr[g[i]]:=npos; sl[npos]:=1; end; re:=maxlongint-10; dem:=0; q:=sum div 2; rem:=sum mod 2; m2:=m2 shr 1; for i:=0 to m2 do begin k:=i; j:=0; temp:=0; while k>0 do begin if k and 1=1 then temp:=temp+b[j]; j:=j+1; k:=k shr 1; end; t:=bs(q-temp,num); if t<re then begin re:=t; dem:=num; end else begin if t=re then dem:=dem+num; end; end; wf; end.
Code mẫu của ladpro98
program LQDDIV; uses math; const maxn=33; fi=''; type pair=record x,y:int64; end; var n,lim,d:longint; res,count,sum,m:int64; a:array[1..maxn] of longint; s:array[1..1 shl (maxn shr 1)] of int64; procedure Enter; var inp:text; i:longint; begin assign(inp,fi);reset(inp); readln(inp,n); for i:=1 to n do begin read(inp,a[i]); inc(a[i],a[i]); inc(sum,a[i]); end; close(inp); lim:=n div 2; m:=sum div 2; res:=high(int64); end; procedure findAbs(key:int64; var p:pair); var l,r,m:longint; begin l:=1;r:=d; while abs(l-r)<>1 do begin m:=(l+r) shr 1; if s[m] = key then begin p.x:=s[m];p.y:=s[m]; exit; end; if s[m] < key then l:=m else r:=m; end; if abs(s[l]-key)=abs(s[r]-key) then begin p.x:=s[l];p.y:=s[r]; exit; end; if abs(s[l]-key)<abs(s[r]-key) then begin p.x:=s[l];p.y:=s[l]; end else begin p.x:=s[r];p.y:=s[r]; end; end; function findL(key:int64):longint; var l,r,m,k:longint; begin l:=1;r:=d; while l<=r do begin m:=(l+r) shr 1; if s[m]>=key then begin k:=m; r:=m-1; end else l:=m+1; end; exit(k); end; function findR(key:int64):longint; var l,r,m,k:longint; begin l:=1;r:=d; while l<=r do begin m:=(l+r) shr 1; if s[m]<=key then begin k:=m; l:=m+1; end else r:=m-1; end; exit(k); end; procedure update(k:int64); var l,r:longint; p:int64; t:pair; begin findAbs(m-k,t); p:=2*(t.x+k)-sum; if abs(p)<res then begin res:=abs(p); l:=findL(t.x); r:=findR(t.y); count:=r-l+1; end else if abs(p) = res then begin l:=findL(t.x); r:=findR(t.y); inc(count,r-l+1); end; end; procedure Gen(i:longint; k:int64); begin if i>lim then begin inc(d); s[d]:=k; exit; end; Gen(i+1,k); Gen(i+1,k+a[i]); end; procedure Back(i:longint; k:int64); begin if i>n then begin update(k); exit; end; back(i+1,k); back(i+1,k+a[i]); end; procedure Sort(l,r:longint); var i,j:longint; p,t:int64; begin if l>=r then exit; i:=l;j:=r; p:=s[random(r-l+1)+l]; repeat while s[i]<p do inc(i); while s[j]>p do dec(j); if i<=j then begin if i<j then begin t:=s[i]; s[i]:=s[j]; s[j]:=t; end; inc(i);dec(j); end; until i>j; Sort(l,j);sort(i,r); end; begin Enter; Gen(1,0); Sort(1,d); Back(lim+1,0); write(res div 2,' ',count div 2); end.
Code mẫu của RR
//Written by RR {$R+,Q+} {$Mode objfpc} {$inline on} uses math; const FINP = ''; FOUT = ''; MAXN = 33; MAXL = 100111; sign : array[0..1] of longint=(-1,1); var f1,f2 : text; n,res,sum : longint; a : array[1..MAXN] of longint; x,e : array[0..1,1..MAXL] of longint; sl : array[0..1] of longint; procedure openF; begin assign(f1,FINP); reset(f1); assign(f2,FOUT); rewrite(f2); end; procedure closeF; begin close(f1); close(f2); end; procedure sort(u,l,r:longint); var i,j,mid,tmp:longint; begin i:=l; j:=r; mid:=x[u,l+random(r-l+1)]; repeat while x[u,i]<mid do inc(i); while x[u,j]>mid do dec(j); if i<=j then begin tmp:=x[u,i]; x[u,i]:=x[u,j]; x[u,j]:=tmp; inc(i); dec(j); end; until i>j; if i<r then sort(u,i,r); if l<j then sort(u,l,j); end; procedure duyet(i,gh,k:longint); var j:longint; begin for j:=0 to 1 do begin sum:=sum+sign[j]*a[i]; if i<gh then duyet(i+1,gh,k) else begin inc(sl[k]); x[k,sl[k]]:=sum; end; sum:=sum-sign[j]*a[i]; end; end; procedure solve; var i,j,tmp,res,count:longint; begin sum:=0; duyet(1,n>>1,0); sort(0,1,sl[0]); sum:=0; duyet(n>>1+1,n,1); sort(1,1,sl[1]); e[0,1]:=1; tmp:=1; for i:=2 to sl[0] do if x[0,i]>x[0,tmp] then begin inc(tmp); x[0,tmp]:=x[0,i]; e[0,tmp]:=1; end else inc(e[0,tmp]); sl[0]:=tmp; e[1,1]:=1; tmp:=1; for i:=2 to sl[1] do if x[1,i]>x[1,tmp] then begin inc(tmp); x[1,tmp]:=x[1,i]; e[1,tmp]:=1; end else inc(e[1,tmp]); sl[1]:=tmp; res:=high(longint); count:=0; j:=sl[1]; for i:=1 to sl[0] do begin while (j>1) and (abs(x[1,j-1]+x[0,i])<abs(x[1,j]+x[0,i])) do dec(j); tmp:=abs(x[1,j]+x[0,i]); if tmp<res then begin res:=tmp; count:=e[0,i]*e[1,j]; end else if tmp=res then inc(count,e[0,i]*e[1,j]); if j>1 then begin tmp:=abs(x[1,j-1]+x[0,i]); if tmp<res then begin res:=tmp; count:=e[0,i]*e[1,j-1]; end else if tmp=res then inc(count,e[0,i]*e[1,j-1]); end; end; writeln(f2,res,' ',count div 2); end; procedure inp; var i:longint; begin read(f1,n); for i:=1 to n do read(f1,a[i]); end; begin openF; inp; solve; closeF; end.
Code mẫu của hieult
#include <cstdio> //#include <conio.h> typedef long long ll; void Quicksort(ll A[],ll lower,ll upper) { ll x = A[(lower + upper) / 2]; ll i = lower; ll j = upper; do{ while(A[i] < x) i ++; while (A[j] > x) j --; if (i <= j) { ll tg=A[i]; A[i]=A[j]; A[j]=tg; i ++; j --; } }while(i <= j); if (j > lower) Quicksort(A, lower, j); if (i < upper) Quicksort(A, i, upper); } ll n,mu2[20],t,so,vitri; ll a[35],b[100000],f[100000],d[100000],tong=0,tt,max,tim,tongtim,gan; int main() { //freopen("LQDDIV1.in","r",stdin); scanf("%lld",&n); for(int i = 1;i<=n;i++) { scanf("%lld",&a[i]); tong+=a[i];} ll m = n/2; ll k = n-m; mu2[0] = 1; for(int i = 1;i<=20;i++) mu2[i] = mu2[i-1]<<1; for(int i = 0;i<mu2[m];i++) { gan = i; tt = 0; for(int j = 1;j<=m;j++){ if(gan%2==1) tt+= a[j]; gan/=2;} b[i+1] = tt; } //printf("%lld\n",mu2[m]); Quicksort(b,1,mu2[m]); //for(int i = 1;i<=10;i++) printf("%lld ",b[i]); t = 0; for(int i = 1;i<=mu2[m];i++) { if(i==1) { f[++t] = b[i]; d[t] = 1;; } else { if(b[i]==b[i-1]) d[t]++; else { f[++t] = b[i]; d[t] = 1; } } } //printf("%lld\n",tong); max = 0; for(int i = 0;i<mu2[k];i++) { gan = i; tt = 0; for(int j = 1;j<=k;j++){ if(gan%2==1) tt+= a[j+m]; gan/=2;} tim = tong/2 - tt; //if(i<16000&& i>=15980) printf("%lld\n",tim); //printf("%lld\n",tt); if(tim<0) continue; ll u = 1, v = t, r; while(v-u>1) { r = (u+v)/2; if(f[r]<=tim) u = r; else v = r; //if(v!=0) } //ll p1 = 45000 ,p2 = 100000; //if(tim == p1*p2 &&i<16000&& i>=15980) printf("%lld %lld\n",u,v); if(f[v]<=tim) { tongtim = f[v]+tt; vitri = v; } else { tongtim = f[u]+tt; vitri = u; } //if(tim == p1*p2 &&i<16000&& i>=15980) printf("***%lld***\n",tongtim); //if(tongtim%1000000000==0) printf("%lld %lld\n",u,v); if(tongtim > max) {max = tongtim; so = d[vitri];} else if(tongtim == max) {so+=d[vitri];} } //prllf("%d\n",tongtim); if(max*2==tong) so/=2; printf("%lld %lld",tong-2*max,so); //getch(); }
Code mẫu của ll931110
#include <iostream> #include <cstdlib> #define MAXV 65550 #define MAXN 33 using namespace std; long long a[MAXV],b[MAXV],d[MAXV],kd[MAXV]; long long stmp,sum,u,delta; int ta[MAXV],tb[MAXV],td[MAXV]; int na,nb,nd,n,tmpd,s[MAXN],k[MAXN],sup; int compare_ints( const void* x, const void* y ) { long long* arg1 = (long long*) x; long long* arg2 = (long long*) y; if( *arg1 < *arg2 ) return -1; else if( *arg1 == *arg2 ) return 0; else return 1; } void attempt(int i,int sup) { for (int j = k[i - 1] + 1; j <= sup; j++) { k[i] = j; stmp += s[j]; kd[++ nd] = stmp; if (j < sup) attempt(i + 1,sup); stmp -= s[j]; } } void precalc() { int i; nd = 0; stmp = 0; attempt(1,sup); qsort( kd, nd + 1, sizeof(long long), compare_ints); tmpd = 0; for (i = 0; i <= nd; i++) td[i] = 0; d[0] = 0; for (i = 0; i <= nd; i++) if (d[tmpd] == kd[i]) td[tmpd]++; else { tmpd++; d[tmpd] = kd[i]; td[tmpd] = 1; } } int main() { int i,xa,xb; long long ncount; //freopen("lqddiv.inp","r",stdin); //freopen("lqddiv.out","w",stdout); scanf("%d", &n); sum = 0; for (i = 1; i <= n; i++) { scanf("%d", &s[i]); sum += s[i]; } sup = n/2; k[0] = 0; precalc(); na = tmpd; for (i = 0; i <= tmpd; i++) { a[i] = d[i]; ta[i] = td[i]; } sup = n; k[0] = n/2; precalc(); nb = tmpd; for (i = 0; i <= tmpd; i++) { b[i] = d[i]; tb[i] = td[i]; } xa = 0; xb = nb; while (xb >= 0 && a[xa] + b[xb] > sum/2) xb--; delta = a[xa] + b[xb]; for (xa = 0; xa <= na; xa++) { while (xb >= 0 && a[xa] + b[xb] > sum/2) xb--; if (xb >= 0 && delta < a[xa] + b[xb]) delta = a[xa] + b[xb]; } u = sum - 2 * delta; xa = 0; xb = nb; ncount = 0; while (xb >= 0 && a[xa] + b[xa] > delta) xb--; for (xa = 0; xa <= na; xa++) { while (xb >= 0 && a[xa] + b[xb] > delta) xb--; if (xb >= 0 && delta == a[xa] + b[xb]) ncount += ta[xa] * tb[xb]; } if (u == 0) ncount = ncount/2; cout << u << " " << ncount; }
Comments