jzoj5330 【NOIP2017提高A组模拟8.22】密码
来源:互联网 发布:淘宝 怎么红包 套现 编辑:程序博客网 时间:2024/06/10 03:48
题面
分析
首先
那么对于
在p进制下理解这个式子,发现任意第i项,后面一大堆不是0就是1.
当什么情况下是1 ? 就是p进制下m+(n-m)是否有进位。如果有进位,那么现在就没有取到这个进位(下取整就类似二进制下右移),那么就是1.
将m视为a,将b视为n-m,那么现在问题就是求
这其实就是库默尔定理。
考虑数位dp。 设
转移比较复杂,所以我直接枚举两个相关状态然后将所有不可能转移剔除。
这样时间++,但是代码好写很多。
注意到这样转移复杂度是p^2的,可以看出转移来转移去都是那几个状态在转移,那么其实系数是有规律的,可以直接计算。 大概就是
0(不卡上界),0(下一位不进位)->0,0,p1+p2< p,
0,0->0,1,p1+p2+1< p
0,1->0,0,p1+p2>=p
0,1->0,1,p1+p2+1>=p
1,0类似
这样的p1,p2对数可以直接计算之类的。
demo
80分。
#include <cstdio>#include <iostream>#include <cstring>using namespace std;typedef long long ll;const ll mo=1e9+7,N=1e3+10,Mx=1e3,gmo=1e8;char s[N];ll np[N],p,k;ll mi[N];ll f[2][3000][2][2],o;// 位数,进位数,卡上界,是否要求下一位进位inline void add(ll &x,ll y) {x=(x+y)%mo;}struct _int { ll a[Mx]; ll& operator[](ll i) {return a[i];}} n;void read(_int &a) { memset(a.a,0,sizeof a.a); scanf("%s",s+1); ll len=strlen(s+1),js=7; for (ll i=len; i; i--) { if (++js==8) ++a[0],js=0; a[a[0]]=a[a[0]]+mi[js]*(s[i]-'0'); }}ll divide(_int &x,ll p) { ll ys=0,o=x[0]; x[0]=0; for (ll i=o; i; i--) { ys=ys*gmo+x[i]; x[i]=ys/p; ys-=x[i]*p; if (x[i] && !x[0]) x[0]=i; } return ys;}int main() { freopen("password.in","r",stdin);// freopen("password.out","w",stdout); mi[0]=1; for (ll i=1; i<=8; i++) mi[i]=mi[i-1]*10; read(n); cin>>p>>k; while (n[0]) np[++np[0]]=divide(n,p); f[o][0][1][0]=1; for (ll i=np[0]; i; i--) { o=1-o; memset(f[o],0,sizeof f[o]); for (ll jj=0; jj<=np[0]-i; jj++) for (ll p1=0; p1<p; p1++) for (ll p2=0; p2<p; p2++) for (ll k=0; k<=1; k++) //卡上界 for (ll kk=0; kk<=1; kk++) for (ll zz=0; zz<=1; zz++) //第i位有没有进位 for (ll z=0; z<=1; z++) { //第i-1位有没有进位 ll fa=p1+p2+z; //是否要求进位 if (zz==0 && fa>=p) continue; if (zz==1 && fa<p) continue;// if (i==1 && z==1) continue; //第一位没得进位// if (i==np[0] && zz==1) continue; //最后一位不能向上进位 //上界 if (fa>=p) fa-=p; if (kk==0 && k==1) continue; if (kk==1 && fa>np[i]) continue; if (kk==1 && k==0 && fa==np[i]) continue; if (kk==1 && k==1 && fa <np[i]) continue;// printf("%d %d %d from %d %d %d,[%d,%d]\n",jj+z,k,z,jj,kk,zz,p1,p2); add(f[o][jj+z][k][z], f[1-o][jj][kk][zz]); } } ll ans=0; for (ll i=k; i<=np[0]; i++) { add(ans, f[o][i][1][0] + f[o][i][0][0]); } cout<<ans<<endl;}
阅读全文
0 0
- jzoj5330 【NOIP2017提高A组模拟8.22】密码
- 【JZOJ5330】【NOIP2017提高A组模拟8.22】密码【51nod1569】二项式系数的个数
- 【NOIP2017提高A组模拟8.22】密码
- 【NOIP2017提高A组模拟8.23】密码
- jzoj. 100031. 【NOIP2017提高A组模拟7.9】外星密码
- 【JZOJ5332】【NOIP2017提高A组模拟8.23】密码
- 【JZOJ5330】【NOIP提高组模拟】密码(库默尔定理、数位DP)
- 【jzoj5328】【NOIP2017提高A组模拟8.22】【世界线】【bitset】
- 5329. 【NOIP2017提高A组模拟8.22】时间机器 map
- JZOJ 5329. 【NOIP2017提高A组模拟8.22】时间机器
- JZOJ 5328. 【NOIP2017提高A组模拟8.22】世界线
- 【NOIP2017提高A组模拟8.22】世界线
- 【NOIP2017提高A组模拟8.22】时间机器
- 世界线 【NOIP2017提高A组模拟8.22】
- 【JZOJ5328】【NOIP2017提高A组模拟8.22】世界线
- 【JZOJ5329】【NOIP2017提高A组模拟8.22】时间机器
- A【NOIP2017提高组模拟12.18】
- 【JZOJ4928】【NOIP2017提高组模拟12.18】A
- 如何盗走别人博客的个人首页的背景图片
- RabbitMQ实践--与Spring的简单整合操作
- MapReduce找共同好友
- hdu4784 SPFA
- AOP面向切面编程
- jzoj5330 【NOIP2017提高A组模拟8.22】密码
- java生成Excel实例代码
- 8.22--练习赛F题--Muddy roads (模拟)
- HDU 6162 Ch’s gift
- hdu6168-多校9&stl&模拟- Numbers
- 缓存失效策略(fifo lru lfu)
- 字符串逆序的几种方式
- Python包管理工具——Pip
- 2017暑假第二阶段第二场 总结