Codeforces 288E - Polo the Penguin and Lucky Numbers(数位 dp+推式子)
纪念自己独立做出来的一道难度 2800 的题。
我们记 \(ans(x)\) 为 \([444...44,x]\) 的答案,显然答案为 \(ans(r)-ans(l)\)
其次我们考虑 \(a_i\) 与 \(a_{i+1}\) 之间有什么联系。
不难发现从 \(a_i\) 变到 \(a_{i+1}\),也就是把 \(a_i\) 末尾一系列 \(7\) 改为 \(4\),再把从右往左数第一个 \(4\) 改为 \(7\)。
这样我们就可以枚举末尾 \(7\) 的个数,假设为 \(cnt\)。
则 \(a_i=xxx...xx4777...77,a_{i+1}=xxx...xx7444...44\)
如果把前面 \(xxx...xx\) 记作 \(X\),那么 \(a_i=X \times 10^{cnt}+4777...77,a_{i+1}=X \times 10^{cnt}+7444...44\)
把 \(a_ia_{i+1}\) 暴力展开,即可得到一个关于 \(X\) 的二次三项式 \(AX^2+BX+C\),其中 \(A,B,C\) 是只与 \(cnt\) 有关的常数,它们具体是什么自己慢慢拆即可,这里就不再赘述了。。
接下来我们就要计算 \(X^2\) 的和,\(X\) 的和以及 \(X\) 的个数,显然可以数位 \(dp\) 预处理。
\(dp[i][0/1]\) 表示考虑到第 \(i\) 位,前 \(i\) 位是否达到上界的答案。
其中 \(dp[i][j]\) 中存三个值:平方和、和、以及个数。
转移可以从 \(dp[i-1][0/1]\) 中转移过来。再根据 \((10x+4)^2=100x^2+80x+16\),\((10x+7)^2=100x^2+140x+49\) 化简。
/*
Contest: -
Problem: Codeforces 288E
Author: tzc_wk
Time: 2020.10.12
*/
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a) a.begin(),a.end()
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,0x3f,sizeof(a))
#define y1 y1010101010101
#define y0 y0101010101010
typedef pair<int,int> pii;
typedef long long ll;
const ll MOD=1e9+7;
char s[100005];int n;
struct data{
ll sqr,cnt,sum;
data(ll _sqr=0,ll _sum=0,ll _cnt=0){
sqr=_sqr;sum=_sum;cnt=_cnt;
}
} dp[100005][2];
ll pw[200005],seven[100005],four[100005];
inline data upd4(data p){
return data(
(p.sqr*100ll+p.sum*80ll+p.cnt*16ll)%MOD,
(p.sum*10ll+p.cnt*4ll)%MOD,(p.cnt));
}
inline data upd7(data p){
return data(
(p.sqr*100ll+p.sum*140ll+p.cnt*49ll)%MOD,
(p.sum*10ll+p.cnt*7ll)%MOD,(p.cnt));
}
inline void add(data &x,data y){
x.sqr+=y.sqr;if(x.sqr>=MOD) x.sqr-=MOD;
x.sum+=y.sum;if(x.sum>=MOD) x.sum-=MOD;
x.cnt+=y.cnt;if(x.cnt>=MOD) x.cnt-=MOD;
}
inline ll get(data x,ll k);
inline ll calc(){
scanf("%s",s+1);n=strlen(s+1);
for(int i=0;i<=n;i++) dp[i][0]=dp[i][1]=data(0,0,0);
dp[0][1]=data(0,0,1);
for(int i=1;i<=n;i++){
dp[i][0]=dp[i][1]=data(0,0,0);
if(s[i]=='4'){
add(dp[i][0],upd4(dp[i-1][0]));
add(dp[i][0],upd7(dp[i-1][0]));
add(dp[i][1],upd4(dp[i-1][1]));
}
else{
add(dp[i][0],upd4(dp[i-1][0]));
add(dp[i][0],upd4(dp[i-1][1]));
add(dp[i][0],upd7(dp[i-1][0]));
add(dp[i][1],upd7(dp[i-1][1]));
}
// printf("%lld %lld %lld\n",dp[i][0].sqr,dp[i][0].sum,dp[i][0].cnt);
// printf("%lld %lld %lld\n",dp[i][1].sqr,dp[i][1].sum,dp[i][1].cnt);
}
ll ans=0;
for(int i=0;i<n;i++){
if(s[i+1]=='4'){
ans=(ans+get(dp[i][0],n-i-1))%MOD;
} else{
ans=(ans+get(dp[i][0],n-i-1))%MOD;
ans=(ans+get(dp[i][1],n-i-1))%MOD;
}
}
// printf("%lld\n",ans);
return ans;
}
int main(){
pw[0]=1;for(int i=1;i<=200002;i++) pw[i]=pw[i-1]*10%MOD;
for(int i=1;i<=100000;i++) seven[i]=(seven[i-1]*10+7)%MOD;
for(int i=1;i<=100000;i++) four[i]=(four[i-1]*10+4)%MOD;
ll L=calc(),R=calc();
printf("%lld\n",(R-L+MOD)%MOD);
return 0;
}
inline ll get(data x,ll k){
// printf("%d %d %d\n",x.sqr,x.sum,x.cnt);
return (seven[k]*four[k]%MOD*x.cnt%MOD+seven[k]*pw[k+1]%MOD*x.sum%MOD+
seven[k]*7%MOD*pw[k]%MOD*x.cnt%MOD+four[k]*pw[k+1]%MOD*x.sum%MOD+
four[k]*4%MOD*pw[k]%MOD*x.cnt%MOD+pw[(k<<1)+2]*x.sqr%MOD+
110*pw[k<<1]%MOD*x.sum%MOD+28*pw[k<<1]%MOD*x.cnt%MOD)%MOD;
}
Codeforces 288E - Polo the Penguin and Lucky Numbers(数位 dp+推式子)的更多相关文章
- Codeforces 914 C. Travelling Salesman and Special Numbers (数位DP)
题目链接:Travelling Salesman and Special Numbers 题意: 给出一个二进制数n,每次操作可以将这个数变为其二进制数位上所有1的和(3->2 ; 7-> ...
- 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP)
2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP) 链接:https://ac.nowcoder.com/acm/contest/163/ ...
- codeforces 55D - Beautiful numbers(数位DP+离散化)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- Codeforces Beta Round #51 D. Beautiful numbers 数位dp
D. Beautiful numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55/p ...
- Codeforces Gym 100418J Lucky tickets 数位DP
Lucky ticketsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view ...
- Educational Codeforces Round 8 D. Magic Numbers 数位DP
D. Magic Numbers 题目连接: http://www.codeforces.com/contest/628/problem/D Description Consider the deci ...
- Codeforces Gym100623J:Just Too Lucky(数位DP)
http://codeforces.com/gym/100623/attachments 题意:问1到n里面有多少个数满足:本身被其各个数位加起来的和整除.例如120 % 3 == 0,111 % 3 ...
- CodeForces 628 D Magic Numbers 数位DP
Magic Numbers 题意: 题意比较难读:首先对于一个串来说, 如果他是d-串, 那么他的第偶数个字符都是是d,第奇数个字符都不是d. 然后求[L, R]里面的多少个数是d-串,且是m的倍数. ...
- CodeForces - 55D - Beautiful numbers(数位DP,离散化)
链接: https://vjudge.net/problem/CodeForces-55D 题意: Volodya is an odd boy and his taste is strange as ...
随机推荐
- 【UE4 C++】 Datatable 读写、导入导出 CSV/Json
Datatable 读取行数据 1. 创建结构体 继承自 FTableRowBase USTRUCT(BlueprintType) struct FSimpleStruct :public FTabl ...
- Coursera Deep Learning笔记 序列模型(三)Sequence models & Attention mechanism(序列模型和注意力机制)
参考 1. 基础模型(Basic Model) Sequence to sequence模型(Seq2Seq) 从机器翻译到语音识别方面都有着广泛的应用. 举例: 该机器翻译问题,可以使用" ...
- [软工顶级理解组] Beta阶段事后分析
目录 设想和目标 计划 资源 变更管理 设计/实现 测试/发布 团队的角色,管理,合作 总结 质量提高 会议截图 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰 ...
- [no code][scrum meeting] Alpha 10
项目 内容 会议时间 2020-04-16 会议主题 用户管理第一版交付 会议时长 15min 参会人员 PM+后端组成员 $( "#cnblogs_post_body" ).ca ...
- Linux多线程实例解析
Linux系统下的多线程遵循POSIX线程接口,称为 pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a.顺便说一下,Linux ...
- Linux多线程编程之详细分析
线程?为什么有了进程还需要线程呢,他们有什么区别?使用线程有什么优势呢?还有多线程编程的一些细节问题,如线程之间怎样同步.互斥,这些东西将在本文中介绍.我见到这样一道面试题: 是否熟悉POSIX多线程 ...
- STM32的I2C框图详解及通讯过程
STM32 的I2C 特性及架构 如果我们直接控制STM32 的两个GPIO 引脚,分别用作SCL 及SDA,按照上述信号的时序要求,直接像控制LED 灯那样控制引脚的输出(若是接收数据时则读取SDA ...
- MyBatis源码分析(三):MyBatis初始化(配置文件读取和解析)
一. 介绍MyBatis初始化过程 项目是简单的Mybatis应用,编写SQL Mapper,还有编写的SqlSessionFactoryUtil里面用了Mybatis的IO包里面的Resources ...
- threading python2 和python3
from __future__ import division from __future__ import print_function import threading balance = 0 d ...
- 链式A+B 牛客网 程序员面试金典 C++ Python
链式A+B 牛客网 程序员面试金典 C++ Python 题目描述 有两个用链表表示的整数,每个结点包含一个数位.这些数位是反向存放的,也就是个位排在链表的首部.编写函数对这两个整数求和,并用链表形式 ...