luoguP3281 [SCOI2013]数数
抄的llj的代码
还有点问题没弄懂,先码着
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=2e5+,mod=;
typedef long long LL;
typedef double db;
using namespace std;
LL power[N],sum[N],S[N],f[N][],ans1,ans2,p[N],q[N],a[N],b[N],B,n,m;; template<typename T>void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} void jian(LL &n) {
if(a[]) a[]--;
else {
a[]=B-;
For(i,,n) {
a[i]--;
if(a[i]>=) break;
a[i]=B-;
}
}
while(n&&!a[n]) n--;
} void pre(int len) {
power[]=; sum[]=;
For(i,,len) power[i]=power[i-]*B%mod;
For(i,,len) sum[i]=(sum[i-]+power[i])%mod;
} void calc(LL s[],int n,LL& ans) {
memset(f,,sizeof(f));
p[]=q[n+]=;
For(i,,n) p[i]=(p[i-]+s[i]*power[i-]%mod)%mod;
Rep(i,n,) q[i]=(q[i+]*B%mod+s[i])%mod;
For(i,,n) {
LL tp=B*(B-)/%mod;
f[i][]=f[i-][]*B%mod+tp*sum[i-]%mod*power[i-]%mod;
tp=s[i]*(s[i]-)/%mod;
f[i][]=(tp*sum[i-]%mod*power[i-]%mod+s[i]*f[i-][]%mod+f[i-][]+s[i]*sum[i-]%mod*(p[i-]+)%mod)%mod;
ans=(ans+(q[i+]>?(q[i+]-):0LL)*f[i][]%mod+f[i][])%mod;
}
} int main() {
#ifdef DEBUG
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
read(B);
read(n); For(i,,n) read(a[n-i+]);
read(m); For(i,,m) read(b[m-i+]); jian(n);
pre();
calc(a,n,ans1);
calc(b,m,ans2);
printf("%lld\n",(ans2-ans1+mod)%mod);
return ;
}
/*
55
5 54 12 6 27 14
7 45 11 25 48 7 45 52
*/
-------------------------------------更新题解---------------------------------------------------
设$f[i][0/1]$表示以从右往左第$i$个数字开头的所有前缀和的和
。
$0$表示$i$前面没有达到上限,$1$表示$i$以前都达到上限
$power[i]表示B^i,sum[i]为power的前缀和$
$f[i][0]=f[i-1][0]*B+B*(B-1)/2*sum[i-1]$
$f[i][0]=f[i-1][0]*B(这一位B种选法)+B*(B-1)/2(这一位B种选法的和)*sum[i-1](这一位对每个前缀的贡献)$
$q[i]为左数第1到第n-i+1个的上限值,p[i]为右数第1至第i的上限值$
$s[i]为右数第i个数的上限值$
$f[i][0]=s[i]*(s[i]-1)/2*sum[i-1]*power[i-1]+s[i]*f[i-1][0]+f[i-1][1]+s[i]*sum[i-1]*q[i+1]-q[i]$
$f[i][1]=s[i]*(s[i]-1)/2*sum[i-1]*power[i-1]$
这一位取不超过0~s[i]-1,即不超过上限,后面就有power[i-1]种情况,每种这一位的贡献都是作为每个前缀的贡献和。
$+s[i]*f[i-1][0]$
这一位取0~s[i]-1的s[i]中情况下,后面的位对前缀和的贡献是f[i-1][0](未到达上限)
$+f[i-1][1]$
这一位取s[i]这一种情况下,后面的位对前缀和的贡献是f[i-1][1](达到上限)
$+s[i]*sum[i-1]*q[i+1]$
这一位取s[i]这一种情况下,这一位对前缀和的贡献
$-f[i-1][0]$计算f时考虑了前导0,完整的串不能包含前导0,减去前面取0(一种情况),这一位也取0的方案
luoguP3281 [SCOI2013]数数的更多相关文章
- 洛谷:P3281 [SCOI2013]数数 (优秀的解法)
刷了这么久的数位 dp ,照样被这题虐,还从早上虐到晚上,对自己无语...(机房里又是只有我一个人,寂寞.) 题目:洛谷P3281 [SCOI2013]数数 题目描述 Fish 是一条生活在海里的鱼, ...
- 2019.03.28 bzoj3326: [Scoi2013]数数(数位dp)
传送门 题意: 一个人数数,规则如下: 确定数数的进制B 确定一个数数的区间[L, R] 对于[L, R] 间的每一个数,把该数视为一个字符串,列出该字符串的所有连续子串对应的B进制数的值. 对所有列 ...
- bzoj3326: [Scoi2013]数数
Description Fish 是一条生活在海里的鱼,有一天他很无聊,就开始数数玩. 他数数玩的具体规则是: 1. 确定数数的进制B 2. 确定一个数数的区间[L, R] 3. 对于[L, R] 间 ...
- 【BZOJ 3326】[Scoi2013]数数
题目描述 Fish 是一条生活在海里的鱼,有一天他很无聊,就开始数数玩.他数数玩的具体规则是: 确定数数的进制B 确定一个数数的区间[L, R] 对于[L, R] 间的每一个数,把该数视为一个字符串, ...
- BZOJ 3326 [SCOI2013]数数 (数位DP)
洛谷传送门 题目: Fish 是一条生活在海里的鱼,有一天他很无聊,就开始数数玩.他数数玩的具体规则是: 确定数数的进制$B$ 确定一个数数的区间$[L, R]$ 对于$[L, R] $间的每一个数, ...
- bzoj 3530: [Sdoi2014]数数 数位dp
题目 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运数. ...
- 【BZOJ】【3530】【SDOI2014】数数
AC自动机/数位DP orz zyf 好题啊= =同时加深了我对AC自动机(这个应该可以叫Trie图了吧……出边补全!)和数位DP的理解……不过不能自己写出来还真是弱…… /************* ...
- BZOJ3530: [Sdoi2014]数数
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 322 Solved: 188[Submit][Status] ...
- 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 682 Solved: 364 Description 我们称一 ...
- COJ 0036 数数happy有多少个?
数数happy有多少个? 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 图图是个爱动脑子.观察能力很强的好学生.近期他正学英语 ...
随机推荐
- linux php5.6 安装
如果之前有安装其他版本PHP,请先卸载干净 配置yum源 追加CentOS 6.5的epel及remi源. # rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fe ...
- vue 通过插槽分发内容
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- python补充4
一 如何判断一个对象是不是函数类型 #方法一def func(arg): if callable(arg): print("是函数"+arg()) else: print(arg) ...
- C/C++ GBK和UTF8之间的转换
{ 关于GBK和UTF-8之间的转换,很多初学者会很迷茫. 一般来说GBK和UTF-8是文字的编码方式,其对应的内码是不一样的,所以GBK和UTF-8的转换需要对内码进行一一映射,然后进行转换. 对于 ...
- 排序+并查集——cf1213F
/* 有向边(pi,pi+1),形成链后进行dfs,求出dfs序 一个联通块内的元素必须是同一个字符,如果最后的联通块个数<k,说明不行 */ #include<bits/stdc++.h ...
- AcWing 156. 矩阵 (哈希二维转一维查询)打卡
给定一个M行N列的01矩阵(只包含数字0或1的矩阵),再执行Q次询问,每次询问给出一个A行B列的01矩阵,求该矩阵是否在原矩阵中出现过. 输入格式 第一行四个整数M,N,A,B. 接下来一个M行N列的 ...
- Java学习之集合(List接口)
List特有的常见方法:有一个共性特点:都可以操作角标 1.添加 void add(int index, E element); void addAll(int index, collection& ...
- 2、什么是session?
session 什么是Session?Session什么时候产生? Session:在计算机中,尤其是在网络应用中,称为“会话控制”.Session 对象存储特定用户会话所需的属性及配置信息.这 ...
- 剑指offer第二版面试题1:数组中重复的数字(JAVA版)
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复的次数.请找出数组中任意一个重复的数字.例如如果输入长度为7的数组{ ...
- Lucene字段
字段是最低单元或索引过程的起点.它代表其中一个键被用于识别要被索引的值的键值对关系.用于表示一个文件的内容的字段中将具有键为“内容”和值,可以包含文本或文档的数字内容的部分或全部. Lucene可以索 ...