传送门

题目大意

有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. JDK自动安装脚本

    A:本脚本运行的机器,Linux B:待安装JDK的机器, Linux 首先在脚本运行的机器A上确定可以ssh无密码登录到待安装jdk的机器B上,然后就可以在A上运行本脚本: 代码如下: $ ./in ...

  2. [SP16580]QTREE7

    luogu vjudge 题意 一棵树,每个点初始有个点权和颜色(输入会给你) 0 u :询问所有u,v路径上的最大点权,要满足u,v路径上所有点的颜色都相同 1 u :反转u的颜色 2 u w :把 ...

  3. k2 4.6.9安装记录-够复杂了

    首先需要准备一台Windows server 2008R2 系统.可以从微软官方下载. 下载地址: http://www.microsoft.com/zh-cn/download/confirmati ...

  4. xj监控端口,模拟登陆脚本

    #!/bin/bash date=`date +%Y%m%d-%H%M` count=0 ip1=124.117.246.195 ip2=124.117.246.194 port1=(443 80 6 ...

  5. extjs控制器调用其他视图的函数实现控件赋值。

  6. Contiki学习笔记

    http://blog.chinaunix.net/uid-9112803-id-2975824.html

  7. Web项目安全相关博客日志大集合(仅供学习及参考)

    强制使用HTTPS --- Tomcat篇 ---通过在tomcat/conf/web.xml中进行配置,从而将http自动转为https.(即强制HSTS)http://blog.csdn.net/ ...

  8. c语言-单链表(二)

    继续复习链表知识点,本章包含单链表的增加,删除,判断是否为空,和链表长度,以及链表的排序 几个知识点 1.链表的判断是否为空 //1.判断链表是否为空 bool isempty_list(PNODE ...

  9. Hibernate面试总结

    SSH原理总结 Hibernate工作原理及为什么要用: 原理: hibernate,通过对jdbc进行封装,对 java类和 关系数据库进行mapping,实现了对关系数据库的面向对象方式的操作,改 ...

  10. sql语句优化方案

    1. 为查询缓存优化你的查询 NOW() 和 RAND() 或是其它的诸如此类的SQL函数都不会开启查询缓存,因为这些函数的返回是会不定的易变的. 所以,你所需要的就是用一个变量来代替MySQL的函数 ...