传送门

题目大意

有2*n个位置,这些位置有的已经填上了数,有的还没有(用?表示),现在让你在还没有填上数的填0~9中的任意数,使得前n个数的乘积等于后n个数的乘积,问有多少种方案。

分析

首先这个题 并没有取模,所以我们要使用高精度。在这个题中我为了加速,将朴素的高精度变成了5个long long类型。然后我们将问题分为先考虑填1~9,再单独考虑填0的情况这两个子问题。

1.考虑填1~9

我们首先会想到的自然是dpij表示考虑到第i个数,乘积为j的方案数。但我们们发现由于乘积可能会很大,所以这样是不可行的。于是我们考虑优化,不难发现我们可以将所有1~9之中的数写为2p13p25p37p4的形式,于是推而广之,对于所有这些有1~9的数构成的数都可以写为这个形式。但是由于空间极小,这样还是不行的,然而对于所有i都只与i-1有关,所以我们可以使用滚动数组。然后我们再经过精妙的计算可以发现对于每个dp数组的答案都不会超过long long的范围,所以我们只需要用long long记录,到统计答案时在转化为高精度形式就行了。对于这一部分的答案就是对于每个不同的四元组(p1,p2,p3,p4)所对应的前半段的dp值乘后半段的dp值。

2.考虑填0

对于每一段,我们可以枚举填1~n个0,而这一段的方案数∑C(n,i)9^(n-i),而最终答案便是前半段求出的值乘上后半段乘上的值。

注意

有可能前半段或者后半段已经填过0了,那我们就要特判这种情况呢,这种情况的计算和考虑填0这一部分的思想相似,只不过可以不填0(即i可以等于0)。

具体实现见代码

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<unordered_map> using namespace std;#define ct cout
#define el endl
#define fi first
#define se second
#define pf printf
#define li long long
#define pb push_back
#define mkp make_pair
#define vi vector<int>
#define y1 y12345678909
#define rii register int
#define pii pair<int,int>
#define ck(x) cout<<x<<endl;
#define ui unsigned int
#define clr(x) memset(x,0,sizeof(x))
#define sp cout<<"---------------------------------------------------"<<endlconst li Tot=1e9;inline int ra(){int _x=0,_f=1;char _s=getchar();while(!isdigit(_s)){if(_s=='-')_f=-1;_s=getchar();}while(isdigit(_s)){_x=(_x<<3)+(_x<<1)+(_s-'0');_s=getchar();}return _x*_f;
}
struct mint {li _[6];int __;
};
mint operator + (mint _x,mint _y){int _k;li _g=0;mint _z;for(rii _i=_x.__+1;_i<=5;++_i)_x._[_i]=0;for(rii _i=_y.__+1;_i<=5;++_i)_y._[_i]=0;if(_x.__>_y.__)_k=_x.__;else _k=_y.__;for(rii _i=1;_i<=_k;++_i){_z._[_i]=(_x._[_i]+_y._[_i]+_g)%Tot;_g=(_x._[_i]+_y._[_i]+_g)/Tot;}if(_g>0){_z._[++_k]=_g;}_z.__=_k;return _z;
}
mint operator - (mint _x,mint _y){int _k;_k=_x.__;for(rii _i=_x.__+1;_i<=5;++_i)_x._[_i]=0;for(rii _i=_y.__+1;_i<=5;++_i)_y._[_i]=0;for(rii _i=1;_i<=_k;++_i){if(_x._[_i]<_y._[_i]){_x._[_i]+=Tot;_x._[_i+1]--;}_x._[_i]-=_y._[_i];}while(_k>1&&_x._[_k]==0)_k--;_x.__=_k;return _x;
}
mint operator * (mint _x,mint _y){int _k;li _g=0;mint _z;for(rii _i=_x.__+1;_i<=5;++_i)_x._[_i]=0;for(rii _i=_y.__+1;_i<=5;++_i)_y._[_i]=0;_k=_x.__+_y.__-1;for(rii _i=0;_i<=5;++_i)_z._[_i]=0;for(rii _i=1;_i<=_x.__;++_i)for(rii _j=1;_j<=_y.__;++_j)_z._[_i+_j-1]+=_x._[_i]*_y._[_j];for(rii _i=1;_i<=_k;++_i){li _a=_z._[_i]+_g;_z._[_i]=_a%Tot;_g=_a/Tot;}while(_g){_z._[++_k]=_g%Tot;_g/=Tot;}while(_k>1&&_z._[_k]==0)_k--;_z.__=_k;return _z;
}
void pr(mint _x){for(rii _i=_x.__;_i>0;--_i)if(_i!=_x.__&&_x._[_i]==0){for(rii _j=1;_j<=9;++_j)cout<<0;}else if(_i!=_x.__){li _m=_x._[_i];int _k=0;while(_m){_m/=10;_k++;}for(rii _j=1;_j<=9-_k;++_j)cout<<0;cout<<_x._[_i];}else cout<<_x._[_i];puts("");
}//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//

li dp[2][2][59][40][21][21];
int a[2][19],tot[2],P[19][5],za,zb,now[3];
mint g[19],c[19][19];
inline void init(){for(rii i=1;i<=9;++i){int m=i;while(m%2==0){P[i][1]++;m/=2;}while(m%3==0){P[i][2]++;m/=3;}while(m%5==0){P[i][3]++;m/=5;}while(m%7==0){P[i][4]++;m/=7;}}return;
}
inline void Get(){for(rii i=0;i<=18;++i)for(rii j=0;j<=18;++j)c[i][j]._[1]=0,c[i][j].__=1; c[0][0].__=1;c[0][0]._[1]=1;for(rii i=1;i<=18;++i)c[i][0].__=c[i][0]._[1]=c[i][i].__=c[i][i]._[1]=1;for(rii i=1;i<=18;++i)for(rii j=1;j<i;++j)c[i][j]=c[i-1][j]+c[i-1][j-1];g[0].__=g[0]._[1]=1;mint nin;nin.__=1,nin._[1]=9;for(rii i=1;i<=18;++i)g[i]=g[i-1]*nin;
}
inline mint pw(mint a,int p){mint res;res.__=res._[1]=1;while(p){if(p&1)res=res*a;a=a*a;p>>=1;}return res;
}
inline void deal(){mint Ans;Ans.__=1,Ans._[1]=0;if(za&&!zb){for(rii i=0;i<=tot[0];++i)for(rii j=0;j<tot[1];++j)Ans=Ans+(g[i]*c[tot[0]][tot[0]-i]*g[j]*c[tot[1]][tot[1]-j]);}else if(!za&&zb){for(rii i=0;i<tot[0];++i)for(rii j=0;j<=tot[1];++j)Ans=Ans+(g[i]*c[tot[0]][tot[0]-i]*g[j]*c[tot[1]][tot[1]-j]);}else {for(rii i=0;i<=tot[0];++i)for(rii j=0;j<=tot[1];++j)Ans=Ans+(g[i]*c[tot[0]][tot[0]-i]*g[j]*c[tot[1]][tot[1]-j]);}pr(Ans);mint ten;ten.__=1;ten._[1]=10;pr(pw(ten,tot[0]+tot[1])-Ans);exit(0);
}
mint xx,yy;
inline mint gt(li wh){mint res;res.__=0;while(wh){res._[++res.__]=wh%Tot;wh/=Tot;}return res;
}
mint ch(li A,li B){xx=gt(A),yy=gt(B);return xx*yy;
}
int main(){freopen("banal.in","r",stdin);freopen("banal.out","w",stdout);memset(P,0,sizeof(P));int n,m;now[0]=now[1]=0;tot[0]=tot[1]=0;za=zb=0;char s;init();Get();n=ra();for(rii i=1;i<=n;++i){cin>>s;if(s=='?')a[0][i]=-1,tot[0]++;else a[0][i]=s-'0';if(s=='0')za++;}for(rii i=1;i<=n;++i){cin>>s;if(s=='?')a[1][i]=-1,tot[1]++;else a[1][i]=s-'0';if(s=='0')zb++;}if(za>0||zb>0){deal();return 0;}clr(dp[0][0]);clr(dp[1][0]);dp[0][0][0][0][0][0]=dp[1][0][0][0][0][0]=1;for(int _=0;_<=1;_++)for(rii i=1;i<=n;++i){now[_]^=1;clr(dp[_][now[_]]);if(a[_][i]!=-1){for(rii p1=0;p1<=i*3;++p1)for(rii p2=0;p2<=i*2;++p2)for(rii p3=0;p3<=i;++p3)for(rii p4=0;p4<=i;++p4){int P1=p1+P[a[_][i]][1],P2=p2+P[a[_][i]][2],P3=p3+P[a[_][i]][3],P4=p4+P[a[_][i]][4];dp[_][now[_]][P1][P2][P3][P4]=dp[_][now[_]][P1][P2][P3][P4]+dp[_][now[_]^1][p1][p2][p3][p4];}}else {for(rii p1=0;p1<=i*3;++p1)for(rii p2=0;p2<=i*2;++p2)for(rii p3=0;p3<=i;++p3)for(rii p4=0;p4<=i;++p4)for(rii j=1;j<=9;++j){int P1=p1+P[j][1],P2=p2+P[j][2],P3=p3+P[j][3],P4=p4+P[j][4];dp[_][now[_]][P1][P2][P3][P4]=dp[_][now[_]][P1][P2][P3][P4]+dp[_][now[_]^1][p1][p2][p3][p4];}}}mint Ans;Ans.__=1,Ans._[1]=0;for(rii p1=0;p1<=n*3;++p1)for(rii p2=0;p2<=n*2;++p2)for(rii p3=0;p3<=n;++p3)for(rii p4=0;p4<=n;++p4){Ans=Ans+ch(dp[0][now[0]][p1][p2][p3][p4],dp[1][now[1]][p1][p2][p3][p4]);}for(rii i=0;i<tot[0];++i)for(rii j=0;j<tot[1];++j)Ans=Ans+(g[i]*c[tot[0]][tot[0]-i]*g[j]*c[tot[1]][tot[1]-j]);pr(Ans);mint ten;ten.__=1;ten._[1]=10;pr(pw(ten,tot[0]+tot[1])-Ans);return 0;
}

转载于:https://www.cnblogs.com/yzxverygood/p/9440745.html

100725B Banal Tickets相关推荐

  1. [Codeforces Gym 101651/100725B] Banal Tickets

    Codeforces Gym 100725 题解: 先分两种情况, 积为000与积非0" role="presentation" style="position ...

  2. POJ 1608 Banal Tickets 笔记

    2N位数,部分数字模糊不清.如果前N位数的乘积等于后N位的乘积被认为是 interesting数,否则是banal数.求可能有多少 interesting数,多少 banal数. 

  3. POJ1608 Banal Tickets

    题目链接 http://poj.org/problem?id=1608 写的不太好,不过还是过了,题解过两天写,先放代码 数据地址:http://neerc.ifmo.ru/archive/2003. ...

  4. POJ的题目分类(两个版本)

    版本一: 简单题 1000A+B Problem 1001Exponentiation 1003 Hangover 1004 Financial Management 1005 I Think I N ...

  5. POJ前面的题目算法思路【转】

    1000 A+B Problem 送分题 49% 2005-5-7 1001 Exponentiation 高精度 85% 2005-5-7 1002 487-3279 n/a 90% 2005-5- ...

  6. POJ 超详细分类

    POJ 各题算法 1000    A+B Problem            送分题     49%    2005-5-7 1001    Exponentiation         高精度   ...

  7. 【POJ】2828 Buy Tickets(线段树+特殊的技巧/splay)

    http://poj.org/problem?id=2828 一开始敲了个splay,直接模拟. tle了.. 常数太大.. 好吧,说是用线段树.. 而且思想很拽.. (貌似很久以前写过貌似的,,) ...

  8. java Thread 类的几种方法

    //后台进程 /** 对于java来说只要还有一个前台线程在运行,这个进程就不结束,如果一个进程* 只有后台线程,这个进程就会结束*/ package xian_cheng;public class ...

  9. owaspbwa tickets

    owaspbwa tickets 来源  https://sourceforge.net/p/owaspbwa/tickets/ 192 SQL Injection in pic_id paramet ...

最新文章

  1. java在己有的类创子类怎么创_如何使用Java创建自己的异常子类
  2. 经典的Java基础面试题集锦
  3. HDUOJ----1166敌兵布阵(线段树单点更新)
  4. 快速生成解决方案 ctrl + shilf + b
  5. 吴恩达深度学习 —— 2.14 向量化逻辑回归的梯度输出
  6. Python+django网页设计入门(16):优化设计复用分页代码
  7. ASP.NET字符显示不正确的解决方法
  8. LSTM及其改进用于视觉任务中
  9. WinForm 的定时器使用
  10. 最近任务 react文章列表
  11. 如何遍历json属性和动态添加属性
  12. cisco路由器配置DHCP实例
  13. Python 作业4+实验三
  14. 【第008问 Unity中什么是UV?】
  15. 光遇脚本弹琴_光遇自动弹琴脚本下载
  16. 如何在国内快速访问Github
  17. 微信也能设置主题了,盘他!
  18. Word 2010之简单图文混排
  19. 史上最通熟易懂的检索式聊天机器人讲解
  20. 《经典算法案例》01-09:如何打印质数表(十列版)

热门文章

  1. 如何对CAD绘图区域进行设置?
  2. js制作点击会自动隐藏的导航栏(固定在在头部的)
  3. Electron-vue开发实战7——命令行调用与系统级别右键菜单项的实现
  4. 亚马逊云计算服务将支持甲骨文数据库
  5. java的round函数加点差_【JAVA】Math.Round()函数常见问题“四舍5入”
  6. 趣玩Python——如何帮女朋友快速抢票
  7. SYBASE 12.5 维护手册 3. 技术专刊
  8. 苹果手机计算机按键会想关掉哪里,苹果手机,你不知道的隐藏功能
  9. 2022-2028全球英语口语练习平台行业调研及趋势分析报告
  10. 安装程序无法继续因为计算机上安,Windows安装无法继续怎么办?Windows安装无法继续的解决方法...