結果
| 問題 |
No.315 世界のなんとか3.5
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2015-12-11 21:48:26 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 143 ms / 2,000 ms |
| コード長 | 2,096 bytes |
| コンパイル時間 | 1,478 ms |
| コンパイル使用メモリ | 161,916 KB |
| 実行使用メモリ | 22,788 KB |
| 最終ジャッジ日時 | 2024-09-15 08:25:12 |
| 合計ジャッジ時間 | 4,923 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 36 |
ソースコード
#include<bits/stdc++.h>
#define REP(x,y,z) for(int x=y;x<=z;x++)
#define FORD(x,y,z) for(int x=y;x>=z;x--)
#define MSET(x,y) memset(x,y,sizeof(x))
#define FOR(x,y) for(__typeof(y.begin()) x=y.begin();x!=y.end();x++)
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define SZ size()
#define M 200005
#define MOD 1000000007
void RI(){}
template<typename... T>
void RI( int& head, T&... tail ) {
scanf("%d",&head);
RI(tail...);
}
using namespace std;
typedef long long LL;
int p;
char a[M],b[M];
LL dp[M][2][2][3];//pos, same, has3, %3
void add(LL &x,LL y)
{
x += y;
if(x>=MOD) x%=MOD;
if(x<0) x = (x%MOD)+MOD;
}
bool has3(int x)
{
while(x)
{
if(x%10==3) return 1;
x /= 10;
}
return false;
}
int solve2(char in[],int same)
{
int n,re=0;
sscanf(in, "%d", &n);
if(!same) n--;
REP(i,0,n) if(i%3==0||has3(i)) if(i%p!=0) re++;
return re;
}
LL solve(char in[],int same)
{
int n=strlen(in);
if(n<=6)
{
return solve2(in,same);
}
int ni,nj,nk,nl;
LL re=0;
MSET(dp,0);
REP(i,0,n-1) in[i]-='0';
REP(i,0,in[0]-1) dp[0][0][i==3][i%3]++;
dp[0][1][in[0]==3][in[0]%3]++;
REP(i,0,n-2)REP(j,0,1)REP(k,0,1)REP(l,0,2) if(dp[i][j][k][l])
{
REP(num,0,9)
{
if(j==1 && num>in[i+1]) continue;
ni = i+1;
nj = (j==1 && num==in[i+1]);
nk = k; if(num==3) nk=1;
nl = (l+num)%3;
add(dp[ni][nj][nk][nl], dp[i][j][k][l]);
}
}
REP(j,0,same) add(re, dp[n-1][j][0][0]);
REP(j,0,same)REP(l,0,2) add(re, dp[n-1][j][1][l]);
/////
int end=n-4; if(p==80) end=n-5; if(p==800)end=n-6;
int mult=1; if(p==80) mult=10; if(p==800)mult=100;
int tail=0, tail2;
REP(i,end+1,n-1) tail=tail*10+in[i];
REP(j,0,1)REP(k,0,1)REP(l,0,2)for(int num=0; num<1000; num+=8)
{
//bigger
tail2 = num*mult;
if(same && j && tail2>tail) continue;
if(!same && j && tail2>=tail) continue;
//no 3
if(k==0 && (l+num)%3!=0 && !has3(num)) continue;
add(re, -dp[end][j][k][l]);
}
return re;
}
int main()
{
LL ans;
while(~scanf("%s%s%d",a,b,&p))
{
ans = solve(b,1)-solve(a,0);
ans = ((ans%MOD)+MOD)%MOD;
printf("%lld\n",ans);
}
return 0;
}