Portal
The first question is a classic two-point, two-point answer \ (ans\), and then sweep from the back, judging to be divided into several segments of the Savior
The second question set \ (f_{i,j}\) represents the number of front \ (i\) divided into \ (j\) , each paragraph and no more than the first answer to the solution, the transfer is from the \ (F_{k,j-1} (K<i, a_{k +1}+...+a_i) (\leq ans) \) transfer over, these \ (k\) is a continuous paragraph, and this section with the DP process as a whole to the right, so a variable record the legal transfer of the sum, and then dynamic maintenance of the Savior
#include <bits/stdc++.h> #define LL long long#define il inline#define re register#define db double#define eps (1e-5) u Sing namespace Std;const int mod=10007;il LL Rd () {ll x=0,w=1;char ch=0; while (ch< ' 0 ' | | Ch> ' 9 ') {if (ch== '-') W=-1;ch=getchar ();} while (ch>= ' 0 ' &&ch<= ' 9 ') {x= (x<<3) + (x<<1) + (ch^48); Ch=getchar ();} return x*w;} int n,m,a[50010],f[2][50010];il bool Check (int mid) {for (int i=1,k=1,su=0;i<=n;i++) {su+=a[i]; if (Su>mid) su=a[i],++k; if (k>m) return false; } return true; int main () {n=rd (), m=rd () +1; int l=0,r=0; for (int i=1;i<=n;i++) a[i]=rd (), L=max (L,a[i]), r+=a[i]; int ans=r; while (l<=r) {int mid= (L+R) >>1; if (check (mid)) ans=mid,r=mid-1; else l=mid+1; } printf ("%d", ans); int nw=1,la=0; for (int i=1,su=0;i<=n;i++) {su+=a[i]; if (Su>ans) break; F[la][i]=1; } int a2=f[la][n]; for (int j=2;j<=m;j++) {memset (f[nw],0,sizeof (F[NW])); for (int i=1,p=1,su=0,tm=0;i<=n;i++) {su+=a[i],tm+=f[la][i-1]; while (Su>ans) su-=a[p],tm-=f[la][p-1],++p; F[nw][i]= (tm= (tm%mod+mod)%mod); } a2= (A2+f[nw][n])%mod; Nw^=1,la^=1; } printf ("%d\n", A2); return 0;}
Luogu P2511 [HAOI2008] sticks split