传送门

题目大意

有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<<"---------------------------------------------------"<<endl const li Tot=1e9; inline int ra(){
int _x=,_f=;char _s=getchar();
while(!isdigit(_s)){if(_s=='-')_f=-;_s=getchar();}
while(isdigit(_s)){_x=(_x<<)+(_x<<)+(_s-'');_s=getchar();}
return _x*_f;
}
struct mint {
li _[];
int __;
};
mint operator + (mint _x,mint _y){
int _k;
li _g=;
mint _z;
for(rii _i=_x.__+;_i<=;++_i)_x._[_i]=;
for(rii _i=_y.__+;_i<=;++_i)_y._[_i]=;
if(_x.__>_y.__)_k=_x.__;
else _k=_y.__;
for(rii _i=;_i<=_k;++_i){
_z._[_i]=(_x._[_i]+_y._[_i]+_g)%Tot;
_g=(_x._[_i]+_y._[_i]+_g)/Tot;
}
if(_g>){
_z._[++_k]=_g;
}
_z.__=_k;
return _z;
}
mint operator - (mint _x,mint _y){
int _k;
_k=_x.__;
for(rii _i=_x.__+;_i<=;++_i)_x._[_i]=;
for(rii _i=_y.__+;_i<=;++_i)_y._[_i]=;
for(rii _i=;_i<=_k;++_i){
if(_x._[_i]<_y._[_i]){
_x._[_i]+=Tot;
_x._[_i+]--;
}
_x._[_i]-=_y._[_i];
}
while(_k>&&_x._[_k]==)_k--;
_x.__=_k;
return _x;
}
mint operator * (mint _x,mint _y){
int _k;
li _g=;
mint _z;
for(rii _i=_x.__+;_i<=;++_i)_x._[_i]=;
for(rii _i=_y.__+;_i<=;++_i)_y._[_i]=;
_k=_x.__+_y.__-;
for(rii _i=;_i<=;++_i)
_z._[_i]=;
for(rii _i=;_i<=_x.__;++_i)
for(rii _j=;_j<=_y.__;++_j)
_z._[_i+_j-]+=_x._[_i]*_y._[_j];
for(rii _i=;_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>&&_z._[_k]==)_k--;
_z.__=_k;
return _z;
}
void pr(mint _x){
for(rii _i=_x.__;_i>;--_i)
if(_i!=_x.__&&_x._[_i]==){
for(rii _j=;_j<=;++_j)cout<<;
}else if(_i!=_x.__){
li _m=_x._[_i];
int _k=;
while(_m){
_m/=;
_k++;
}
for(rii _j=;_j<=-_k;++_j)cout<<;
cout<<_x._[_i];
}
else cout<<_x._[_i];
puts("");
} //---------------------------------------------------------------------------//
//---------------------------------------------------------------------------// li dp[][][][][][];
int a[][],tot[],P[][],za,zb,now[];
mint g[],c[][];
inline void init(){
for(rii i=;i<=;++i){
int m=i;
while(m%==){
P[i][]++;
m/=;
}
while(m%==){
P[i][]++;
m/=;
}
while(m%==){
P[i][]++;
m/=;
}
while(m%==){
P[i][]++;
m/=;
}
}
return;
}
inline void Get(){
for(rii i=;i<=;++i)
for(rii j=;j<=;++j)
c[i][j]._[]=,c[i][j].__=;
c[][].__=;
c[][]._[]=;
for(rii i=;i<=;++i)
c[i][].__=c[i][]._[]=c[i][i].__=c[i][i]._[]=;
for(rii i=;i<=;++i)
for(rii j=;j<i;++j)
c[i][j]=c[i-][j]+c[i-][j-];
g[].__=g[]._[]=;
mint nin;
nin.__=,nin._[]=;
for(rii i=;i<=;++i)g[i]=g[i-]*nin;
}
inline mint pw(mint a,int p){
mint res;
res.__=res._[]=;
while(p){
if(p&)res=res*a;
a=a*a;
p>>=;
}
return res;
}
inline void deal(){
mint Ans;
Ans.__=,Ans._[]=;
if(za&&!zb){
for(rii i=;i<=tot[];++i)
for(rii j=;j<tot[];++j)
Ans=Ans+(g[i]*c[tot[]][tot[]-i]*g[j]*c[tot[]][tot[]-j]);
}else if(!za&&zb){
for(rii i=;i<tot[];++i)
for(rii j=;j<=tot[];++j)
Ans=Ans+(g[i]*c[tot[]][tot[]-i]*g[j]*c[tot[]][tot[]-j]);
}else {
for(rii i=;i<=tot[];++i)
for(rii j=;j<=tot[];++j)
Ans=Ans+(g[i]*c[tot[]][tot[]-i]*g[j]*c[tot[]][tot[]-j]);
}
pr(Ans);
mint ten;
ten.__=;
ten._[]=;
pr(pw(ten,tot[]+tot[])-Ans);
exit();
}
mint xx,yy;
inline mint gt(li wh){
mint res;
res.__=;
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,,sizeof(P));
int n,m;
now[]=now[]=;
tot[]=tot[]=;
za=zb=;
char s;
init();
Get();
n=ra();
for(rii i=;i<=n;++i){
cin>>s;
if(s=='?')a[][i]=-,tot[]++;
else a[][i]=s-'';
if(s=='')za++;
}
for(rii i=;i<=n;++i){
cin>>s;
if(s=='?')a[][i]=-,tot[]++;
else a[][i]=s-'';
if(s=='')zb++;
}
if(za>||zb>){
deal();
return ;
}
clr(dp[][]);clr(dp[][]);
dp[][][][][][]=dp[][][][][][]=;
for(int _=;_<=;_++)
for(rii i=;i<=n;++i){
now[_]^=;
clr(dp[_][now[_]]);
if(a[_][i]!=-){
for(rii p1=;p1<=i*;++p1)
for(rii p2=;p2<=i*;++p2)
for(rii p3=;p3<=i;++p3)
for(rii p4=;p4<=i;++p4){
int P1=p1+P[a[_][i]][],P2=p2+P[a[_][i]][],
P3=p3+P[a[_][i]][],P4=p4+P[a[_][i]][];
dp[_][now[_]][P1][P2][P3][P4]=
dp[_][now[_]][P1][P2][P3][P4]+
dp[_][now[_]^][p1][p2][p3][p4];
}
}else {
for(rii p1=;p1<=i*;++p1)
for(rii p2=;p2<=i*;++p2)
for(rii p3=;p3<=i;++p3)
for(rii p4=;p4<=i;++p4)
for(rii j=;j<=;++j){
int P1=p1+P[j][],P2=p2+P[j][],P3=p3+P[j][],P4=p4+P[j][];
dp[_][now[_]][P1][P2][P3][P4]=
dp[_][now[_]][P1][P2][P3][P4]+
dp[_][now[_]^][p1][p2][p3][p4];
}
}
}
mint Ans;
Ans.__=,Ans._[]=;
for(rii p1=;p1<=n*;++p1)
for(rii p2=;p2<=n*;++p2)
for(rii p3=;p3<=n;++p3)
for(rii p4=;p4<=n;++p4){
Ans=Ans+ch(dp[][now[]][p1][p2][p3][p4],dp[][now[]][p1][p2][p3][p4]);
}
for(rii i=;i<tot[];++i)
for(rii j=;j<tot[];++j)
Ans=Ans+(g[i]*c[tot[]][tot[]-i]*g[j]*c[tot[]][tot[]-j]);
pr(Ans);
mint ten;
ten.__=;
ten._[]=;
pr(pw(ten,tot[]+tot[])-Ans);
return ;
}

100725B Banal Tickets的更多相关文章

  1. POJ2828 Buy Tickets[树状数组第k小值 倒序]

    Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 19012   Accepted: 9442 Desc ...

  2. ACM: FZU 2112 Tickets - 欧拉回路 - 并查集

     FZU 2112 Tickets Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u P ...

  3. Tickets——H

    H. Tickets Jesus, what a great movie! Thousands of people are rushing to the cinema. However, this i ...

  4. POJ 2828 Buy Tickets(线段树 树状数组/单点更新)

    题目链接: 传送门 Buy Tickets Time Limit: 4000MS     Memory Limit: 65536K Description Railway tickets were d ...

  5. 【poj2828】Buy Tickets

    Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get ...

  6. [poj2828] Buy Tickets (线段树)

    线段树 Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must ...

  7. POJ 2828 Buy Tickets

    Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get ...

  8. Buy Tickets(线段树)

     Buy Tickets Time Limit:4000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit ...

  9. 【poj2828】Buy Tickets 线段树 插队问题

    [poj2828]Buy Tickets Description Railway tickets were difficult to buy around the Lunar New Year in ...

随机推荐

  1. hdoj-1032-The 3n + 1 problem(坑题)

     题目链接 //巨坑的一道题,输入的m,n要判断大小,输出还要按照原来的顺序,范围还是i<=n<=j #include <iostream> #include <cstd ...

  2. ICE的连接机制

    1.当使用ICE的proxy进行方法调用时,ICE运行环境会建立一个到服务器的连接.当proxy提供了多个endpoint时   默认的ICE运行环境选择endpoint的行为为random,可以通过 ...

  3. cocos2dx混合模式应用———制作新手引导高亮区域 (2.2.0)

    cocos2dx混合模式应用———制作新手引导高亮区域 转自:http://www.cnblogs.com/mrblue/p/3455775.html 首先,效果预览一下 高亮区域的图片: 示例代码: ...

  4. 20179203 《Linux内核原理与分析》第十一周作业

    一.环境的使用和搭建 首先我的攻击机和靶机都搭建在虚拟机上,选用的是VMware Workstation Pro虚拟机. 攻击机选用的是Linux kali 2017.2版本,而靶机安装的是XP sp ...

  5. 4、运行成功的Demo(PyCharm+Selenium)

    1.打开PyCharm,新建一个python.file,输入代码“from selenium import webdriver”报错的解决方法 (1)PyCharm没有找到正确的python,在“Fi ...

  6. 第11篇 PSR-0 规范

    Mandatory A fully-qualified namespace and class must have the following structure \<Vendor Name&g ...

  7. url出现特殊字符,需要进行编码

    1) 网络访问请求:中文空格字符编码/解码 stringByAddingPercentEscapesUsingEncoding(只对 `#%^{}[]|\"<> 加空格共14个字 ...

  8. webrtc doubango linphone

    1.doubango官网:http://www.doubango.org/ 2.doubango是一个开源的VOIP基础平台, 并能用于嵌入式和桌面系统的开源框架,该框架使用ANSCI-C编写,具有很 ...

  9. Generate web.xml deployment descriptor

    eclipse 使用tomcat7.0建立Dynamic Web Project 时,next至步骤“Web Module”,此时勾选选项“Generate web.xml deployment de ...

  10. C#改变LInqToSQL的引用地址,读取config的数据库字符串

    C#改变LInqToSQL的引用地址,读取config的数据库字符串修改Properties 下 Settings.Settings 下 Settings.Designer.cs 下 return ( ...