题意:
给出一个16进制数,自身+n-1。超过FFFFFFFF后从0开始算。每个数的贡献如图所示。问贡献和为多少。
思路:
刚接触数位dp,队友说是数位dp还让我给否定了...惭愧...(PS: 0x 十六进制 0 八进制)
对于这个题我们需要注意的就是如果超过0xffffffff的话 需要用
solve(0xffffffff)-(solve(l-1)-solve(r));
如果没超过0xffffffff 就是solve(r)-solve(l-1):
下面就是套模板了...
#include<bits/stdc++.h>
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 100000007
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int cost[20]={6,2,5,5,4,5,6,3,7,6,6,5,4,5,5,4};
ll mod=(ll)0xffffffff;
int t;
ll n,dp[10][maxn];
int bit[50];
ll cnt(char *s)
{
ll ans=0;
for(int i=0;i<8;i++)
{
if(s[i]>='0'&&s[i]<='9')
ans=ans*16+s[i]-'0';
else
ans=ans*16+s[i]-'A'+10;
}
return ans;
}
ll dfs(int pos,ll sum,int flag)
{
if(pos<0)
return sum;
if(flag&&dp[pos][sum]!=-1)
return dp[pos][sum];
int d=flag?15:bit[pos];
ll ans=0;
for(int i=0;i<=d;i++)
{
ans+=dfs(pos-1,sum+cost[i],flag||i!=d);
}
if(flag)
dp[pos][sum]=ans;
return ans;
}
ll solve(ll k)
{
CLR(bit,0);
int len=0;
while(k)
{
bit[len++]=k%16;
k/=16;
}
return dfs(7,0,0);
}
int main()
{
char str[50];
CLR(dp,-1);
Ri(t);
W(t)
{
Rl(n),scanf("%s",str);
n--;
ll l=cnt(str);
//Pl(tmp);
if(l+n>mod)
{
ll r=(l+n-1)%mod;
Pl(solve((ll)0xffffffff)-(solve(l-1)-solve(r)));
}
else
{
ll r=l+n;
Pl(solve(r)-solve(l-1));
}
}
return 0;
}
还有就是数据量太大,cin输出string尴尬的一直TLE orz...