zhber 有好多做过的题没写下来，如果我还能记得就补吧

3 2
1
1
10

## Sample Output

10 2

n<=50000, 0<=m<=min(n-1,1000).
1<=Li<=1000.

#include<cstdio>
#include<cstring>
#define maxn 100001
#define mod 10007
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
}
int n,m;
int a[maxn];
int s[maxn];
int q[maxn];
int f[2][maxn];
int l,r,ans,ans2;
inline bool mark(int k)
{
int sum,piece=m,now=1;
while (piece&&now<=n)
{
sum=0;
while (now<=n&&sum+a[now]<=k) sum+=a[now++];
piece--;
}
if (now<=n&&s[n]-s[now-1]>k) return 0;
return 1;
}
inline void init()
{
n=read();
m=read();
for (int i=1;i<=n;i++)
{
a[i]=read();
s[i]=s[i-1]+a[i];
if (a[i]>l) l=a[i];
}
r=s[n];
}
inline void bsearch(
{
while (l<=r)
{
int mid=(l+r)>>1;
if (mark(mid)){ans=mid;r=mid-1;}
else l=mid+1;
}
printf("%d ",ans);

}
inline void dp()
{
f[0][0]=1;
int pre,cur,res;
for (int i=1;i<=m;i++)
{
pre=i&1;
cur=pre^1;
int h=1,t=1;
q[1]=0;res=f[cur][0];
for (int j=1;j<=n;j++)
{
while (h<=t&&s[j]-s[q[h]]>ans)
{
res=(res-f[cur][q[h++]])%mod;
res=(res+mod)%mod;
}
f[pre][j]=res;
q[++t]=j;res=(res+f[cur][j])%mod;
}
for (int j=n-1;j>0;j--)
{
if (s[n]-s[j]>ans) break;
ans2=(ans2+f[pre][j])%mod;
}
memset(f[cur],0,sizeof f[cur]);
}
printf("%d\n",ans2);
}
int main()
{
init();
bsearch();
dp();
}
posted on 2014-07-18 17:23  zhber  阅读(162)  评论(0编辑  收藏