您的位置:首页 > 其它

【bzoj 3598】: [Scoi2014]方伯伯的商场之旅

2015-03-19 13:08 441 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=3598

DP啊DP

如果枚举mid的话会很麻烦。。。可能还会爆空间

改成转移一切都不是问题~

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
//////////////////////////////////////////////////
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define INE(i,u) for(int i=head[u];~i=i=e[i].next)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define X first
#define Y second
typedef pair<LL,LL>pll;
//////////////////////////////////////////////////
LL L,R,k;
int bit[60];
pll dp[60];
LL dp2[60][3000][60];
//////////////////////////////////////////////////
pll dfs(int pos,bool limit)
{
if(!pos) return pll(1,0);
if(!limit&&~dp[pos].X) return dp[pos];
pll res(0,0);
int upp=limit?bit[pos]:k-1;
rep(i,0,upp)
{
pll ret=dfs(pos-1,limit&&i==upp);
res.X+=ret.X;
res.Y+=ret.Y+ret.X*i*(pos-1);
}
if(!limit) dp[pos]=res;
return res;
}
LL dfs2(int pos,int c,int mid,bool limit)
{
if(!pos) return c;
if(!limit&&~dp2[pos][c][mid]) return dp2[pos][c][mid];
int upp=limit?bit[pos]:k-1;
LL res=0;
rep(i,0,upp)
{
int delta=i;
if(pos<mid) delta=-delta;
int nc=c+delta;
if(nc<0) continue;
res+=dfs2(pos-1,nc,mid,limit&&i==upp);
}
if(!limit) dp2[pos][c][mid]=res;
return res;
}
LL solve(LL n)
{
for(*bit=0;n;n/=k) bit[++*bit]=n%k;
LL res=dfs(*bit,1).Y;
rep(i,2,*bit)
res-=dfs2(*bit,0,i,1);
return res;
}
//////////////////////////////////////////////////
void input()
{
MS(dp,-1); MS(dp2,-1);
cin>>L>>R>>k;
}
void solve()
{
cout<<solve(R)-solve(L-1)<<endl;
}
int main()
{
freopen("shop.in","r",stdin); freopen("shop.out","w",stdout);
input(),solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: