【BZOJ3326】数数 数学题
来源:互联网 发布:开淘宝微店能赚钱吗 编辑:程序博客网 时间:2024/06/06 20:38
3326: [Scoi2013]数数
Time Limit: 1 Sec Memory Limit: 64 MB
Description
Fish 是一条生活在海里的鱼,有一天他很无聊,就开始数数玩。
他数数玩的具体规则是:
1. 确定数数的进制B
2. 确定一个数数的区间[L, R]
3. 对于[L, R] 间的每一个数,把该数视为一个字符串,列出该字符串的每一个(连续的)子串对应的B进制数的值。
4. 对所有列出的数求和。
现在Fish 数了一遍数,但是不确定自己的结果是否正确了。由于[L, R] 较大,他没有多余精力去验证是否正确,你能写一个程序来帮他验证吗?
Input
输入包含三行。
第一行仅有一个数B,表示数数的进制。
第二行有N +1 个数,第一个数为N,表示数L 在B 进制下的长度为N,接下里的N个数从高位到低位的表示数L 的具体每一位。
第三行有M+ 1 个数,第一个数为M,表示数R 在B 进制下的长度为M,接下里的M个数从高位到低位的表示数R 的具体每一位。
20% 数据,0 <= R <= L <= 10^5。
50% 数据,2 <= B <= 1000,1 <= N,M <= 1000。
100% 数据,2 <= B <= 10^5,1 <= N,M <= 10^5。
Output
输出仅一行,即按照Fish 数数规则的结果,结果用10 进制表示,由于该数可能很大,输出该数模上20130427的模数。
Sample Input
10
3 1 0 3
3 1 0 3
Sample Output
120
Hint
[103, 103] 之间仅有数103,该数的所有子串包括1, 10, 103, 0, 03, 3,其和为120。
说是数位DP……乱推呗……老套路,
更恶心的是后面的统计答案。
套路还是老样子……从高位向低位扫,处理完每位数字小于这位本身上限的情况,往后统计的时候认为这一位的数字等于上限……在处理某一位的时候,要考虑三个部分:只包含这一位之前的所有位中的某些位的串,包含这一位的字串,以及只包含这一位后面的某些位的串。同时,对于第一位还要特殊处理,因为题目是不允许前导0的……呐,具体实现就不说了,还是看看代码吧(博主推得吐血)……
#include<cstdio>#include<iostream>#define maxn 100000using namespace std;typedef long long LL;const LL p=20130427,inv2=(p+1)/2;LL b,numl[maxn+10],numr[maxn+10],bp[maxn+10],f[maxn+10],h[maxn+10],m[maxn+10],s[maxn+10];LL cal(int n,LL *num){ LL ret=0,r=num[1],pre=0,suf=0; ret=(f[n-1]-h[n-1]+p+(r-1)*(2*f[n-1]%p+r*bp[n-1]%p*s[n-1]%p+2*m[n])%p*inv2%p)%p; pre=suf=r; for(int i=2;i<=n;i++){ r=num[i]; ret=(ret+r*f[n-i]%p+(r*b%p*suf%p+r*(r-1)/2%p*i%p)*bp[n-i]%p*s[n-i]%p+r*i%p*m[n-i+1]%p+pre*r%p*bp[n-i]%p)%p; suf=(suf*b+i*r)%p; pre=(pre+suf)%p; } return ret;}int main(){ int nl,nr; scanf("%d",&b); scanf("%d",&nl); for(int i=1;i<=nl;i++)scanf("%lld",&numl[i]); scanf("%d",&nr); for(int i=1;i<=nr;i++)scanf("%lld",&numr[i]); bp[0]=s[0]=1; for(int i=1;i<=maxn+5;i++)bp[i]=bp[i-1]*b%p; for(int i=1;i<=maxn+5;i++)s[i]=(b*s[i-1]+1)%p; for(int i=1;i<=maxn+5;i++){ m[i]=bp[i-1]*(s[i-1]-i+p)%p*inv2%p; f[i]=(b*f[i-1]%p+bp[i]*(bp[i]-1+p)%p*inv2%p+b*m[i]%p); h[i]=(h[i-1]+m[i])%p; } //因为我那套路处理的是小于某个数的所有数,所以我们把上界暴力加一…… numr[nr]++; for(int i=nr;i;i--)if(numr[i]==b){ numr[i]=0; numr[i-1]++; }else break; if(numr[0]){ for(int i=nr;i>=0;i--)numr[i+1]=numr[i]; nr++; } cout<<(cal(nr,numr)-cal(nl,numl)+p)%p<<endl; return 0;}
再附个暴力……方便验算= =
#include<cstdio>#include<iostream>using namespace std;typedef long long LL;int num[20];const LL p=20130427;LL find(int x){ int n=0; while(x){ num[++n]=x%10; x/=10; } LL ret=0; for(int i=n;i;i--){ LL t=0; for(int j=i;j;j--){ t=(t*10+num[j])%p; // printf("%d\n",t); ret+=t; ret%=p; } } return ret;}int main(){ //freopen("test.out","w",stdout); int a=339,b=2359; LL ans=0; for(int i=a;i<=b;i++)ans+=find(i); cout<<ans%p<<endl;}
- 【BZOJ3326】数数 数学题
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- 数数
- [BZOJ2049]洞穴勘测[BZOJ2157]旅游Link-Cut Tree模板题
- Android Annotation基础教程
- mysql
- 什么是不可修改对象(Immutable Object)?你能否写一个例子?
- 架构师主要工作
- 【BZOJ3326】数数 数学题
- struts2的form提交时action属性的配置
- Dreamweaver 支持 scss 设置
- Android ListView GridView 错位
- 提示错误:arm-linux-gcc: Command not found
- 欢迎使用CSDN-markdown编辑器
- Rabbitmq 学习(1)python版
- epoll示例程序——服务端
- MapReduce初级经典案例实现