统计方案数,要么组合数,要么递推(dp)了。

这是有模拟赛历史以来爆炸最狠的一次

  • T1写了正解,也想到开long long,但是开错了地方然后数组开大了结果100->0
  • T3看错题本来简单模拟又给我搞成0分
  • T5差分约束本来很简单但是又被我胡搞炸掉了.....

本题T4,难到爆炸的T2把我困住了.....

先讲讲考试看道题的想法:

思考了一会吗,推出几个结论,然后准备写了,感觉可以短时间A掉,结果被T2困住,一小时只优化掉了一个没啥用的n..(n^5logn的复杂度用爱过题)

然后现在来讲讲正解(也是时候背高精板子了)

首先,很容易想到,对于有0出现的数字,其结果一定是0,从而得出一个结论,对于0的结果就是10^n-9^n(不要让我证明)

然后进一步想到,对于给定k进行质因数分解,然后组合&&排列算方案数(我就是这里走了与dp不同的路)

但是发现这样并不好处理,进一步发现,如果k的质因数有大于10的,那么直接输出0(因为一个数位没法装下两个数)

然后,我在这里就暴毙了。

接下来就是正解了。

有了以上结论,我们能非常不容易地想到dp方程式:

$f[i][j][k][m][l]$表示在前i位中,2,3,5,7分别用了几次;

这个转移是真的令人折服。

for (int i = ; i <= n;i++)
{
for (int j = a2; j >= ;j--)
{
for (int k = a3; k >= ;k--)
{
for (int l = a5; l >= ;l--)
{
for (int m = a7; m >= ;m--)
{
if(j>=)
f[j][k][l][m] = f[j - ][k][l][m] + f[j][k][l][m];//
if(k>=)
f[j][k][l][m] = f[j][k - ][l][m] + f[j][k][l][m];//
if(j>=)
f[j][k][l][m] = f[j - ][k][l][m] + f[j][k][l][m];//
if(l>=)
f[j][k][l][m] = f[j][k][l - ][m] + f[j][k][l][m];//
if(j&&k)
f[j][k][l][m] = f[j - ][k - ][l][m] + f[j][k][l][m];//
if(m>=)
f[j][k][l][m] = f[j][k][l][m - ] + f[j][k][l][m];//
if(j>=)
f[j][k][l][m] = f[j - ][k][l][m] + f[j][k][l][m];//
if(k>=)
f[j][k][l][m] = f[j][k - ][l][m] + f[j][k][l][m];//
}
}
}
}
}

对每一位数进行分解,从而得出的方程,其实也不难想,只是没接触过所以想不到

于是,就可以开心地dp了吗?

不,你想死。

当n<=6的时候,方案数就已经上10万了,那么五十....

嘶~~

没有模数??

只能写高精了。

$$但!是!$$

高精*5维数组,会炸空间的....

所以,还要像01背包那样滚掉一维,所以就出现了上述的4维方程式。

于是,代码(这个高精的缺点就在:它太长了!!!!):

#include<bits/stdc++.h>
using namespace std;
const int maxn=;
#define re register
#define max(x,y) ((x)>(y)?(x):(y))
struct node
{
int len,s[];
node(){memset(s,,sizeof(s)); len=;}
node(int val) {*this=val;}
node(const char *val) {*this=val;}
node operator = (const int &val)
{
re char s[];
sprintf(s,"%d",val);
*this=s;return *this;
}
node operator = (const char *val)
{
len=strlen(val);
while(len>&&val[]=='') ++val,len--;
for(re int i=;i<len;++i) s[i]=val[len-i-]-'';
return *this;
}
inline void deal()
{
while(len>&&!s[len-]) len--;
}
node operator + (const node &a) const
{
node res;res.len=;
re int top=max(len,a.len),add=;
for(re int i=;add||i<top;++i)
{
re int now=add;
if(i<len) now+=s[i];
if(i<a.len) now+=a.s[i];
res.s[res.len++]=now%;
add=now/;
}
return res;
}
node operator - (const node &a) const
{
node res; res.len=;re int del=;
for(re int i=;i<len;++i){
re int now=s[i]-del;
if(i<a.len) now-=a.s[i];
if(now>=) del=;
else del=,now+=;
res.s[res.len++]=now;
}
res.deal(); return res;
}
node operator * (const node &a) const
{
node res; res.len=len+a.len;
for(re int i=;i<len;++i)
for(re int j=;j<a.len;++j)
res.s[i+j]+=s[i]*a.s[j];
for(re int i=;i<res.len;++i)
res.s[i+]+=res.s[i]/,res.s[i]%=;
res.deal(); return res;
}
node operator / (const node &a) const
{
node res,cur=;res.len=len;
for(re int i=len-;~i;--i){
cur=cur*,cur.s[]=s[i];
while(cur>=a)
cur-=a,res.s[i]++;
}
res.deal(); return res;
}
node operator % (const node &a) const
{
node res=*this/a;
return *this-res*a;
}
node operator += (const node &a) {*this=*this+a; return *this;}
node operator -= (const node &a) {*this=*this-a; return *this;}
node operator *= (const node &a) {*this=*this*a; return *this;}
node operator %= (const node &a) {*this=*this%a; return *this;}
bool operator < (const node &a) const
{
if(len!=a.len) return len<a.len;
for(re int i=len-;~i;i--)
if(s[i]!=a.s[i]) return s[i]<a.s[i];
return false;
}
bool operator > (const node &a) const {return a<*this;}
bool operator <= (const node &a) const {return !(*this>a);}
bool operator >= (const node &a) const {return !(*this<a);}
bool operator == (const node &a) const {return !(*this>a||*this<a);}
bool operator != (const node &a) const {return *this>a||*this<a;}
}; inline void print(const node &a)
{
for(re int i=a.len-;~i;--i)
printf("%d",a.s[i]); puts("");
}
int n,k,m;
node f[][][][];
int a2,a3,a5,a7;
void solve()
{
node a,b;
a.s[]=;
b.s[]=;
for(int i=;i<=n;i++)
{
a*=;
b*=;
}
b-=a;
print(b);
}
int main()
{
scanf("%d%d", &n, &k);
if(k==)
{
solve();
return ;
}
int t = k;
while (k % == )
a2++,k /= ;
while (k % == )
a3++, k /= ;
while (k % == )
a5++, k /= ;
while (k % == )
a7++, k /= ;
if(k!=)
{
printf("");
return ;
}
f[][][][].s[] = ;
f[][][][].len = ;
for (int i = ; i <= n;i++)
{
for (int j = a2; j >= ;j--)
{
for (int k = a3; k >= ;k--)
{
for (int l = a5; l >= ;l--)
{
for (int m = a7; m >= ;m--)
{
if(j>=)
f[j][k][l][m] = f[j - ][k][l][m] + f[j][k][l][m];//
if(k>=)
f[j][k][l][m] = f[j][k - ][l][m] + f[j][k][l][m];//
if(j>=)
f[j][k][l][m] = f[j - ][k][l][m] + f[j][k][l][m];//
if(l>=)
f[j][k][l][m] = f[j][k][l - ][m] + f[j][k][l][m];//
if(j&&k)
f[j][k][l][m] = f[j - ][k - ][l][m] + f[j][k][l][m];//
if(m>=)
f[j][k][l][m] = f[j][k][l][m - ] + f[j][k][l][m];//
if(j>=)
f[j][k][l][m] = f[j - ][k][l][m] + f[j][k][l][m];//
if(k>=)
f[j][k][l][m] = f[j][k - ][l][m] + f[j][k][l][m];//
}
}
}
}
}
print(f[a2][a3][a5][a7]);
return ;
}

「NOIP模拟赛」数位和乘积(dp,高精)的更多相关文章

  1. 「NOIP模拟赛」Round 3

    Tag 计数+LIS, 二分+ST表, 计数+记搜 A. 改造二叉树 Description 题面 Solution 如果目标序列非严格递增,或者说目标序列是不下降的,那么答案就是 \(n\) 减去最 ...

  2. 「NOIP模拟赛」Round 2

    Tag 递推,状压DP,最短路 A. 篮球比赛1 题面 \(Milky\ Way\)的代码 #include <cstdio> const int N = 2000, xzy = 1e9 ...

  3. 「CSP-S模拟赛」2019第四场

    「CSP-S模拟赛」2019第四场 T1 「JOI 2014 Final」JOI 徽章 题目 考场思考(正解) T2 「JOI 2015 Final」分蛋糕 2 题目 考场思考(正解) T3 「CQO ...

  4. 「CSP-S模拟赛」2019第三场

    目录 T1 「POI2007」山峰和山谷 Ridges and Valleys 题目 考场思路(几近正解) 正解 T2 「JOI 2013 Final」 现代豪宅 题目 考场思路(正解) T3 「SC ...

  5. 【模拟】HHHOJ#251. 「NOIP模拟赛 伍」高精度

    积累模拟经验 题目描述 维护一个二进制数,支持如下操作 "+" 该数加 11 "-" 该数减 11 "*" 该数乘 22 "\&q ...

  6. Solution -「牛客 NOIP 模拟赛」打拳

    \(\mathcal{Description}\)   现 \(2^n\) 个人进行淘汰赛,他们的战力为 \(1\sim 2^n\),战力强者能战胜战力弱者,但是战力在集合 \(\{a_m\}\) 里 ...

  7. 「CSP-S模拟赛」2019第二场

    目录 T1 Jam的计数法 题目 考场思路(正解) T2 「TJOI / HEOI2016」排序 题目 考场思路(假正解) 正解 T3 「THUWC 2017」随机二分图 题目 考场思路 正解 这场考 ...

  8. 「CSP-S模拟赛」2019第一场

    目录 T1 小奇取石子 题目 考场思路 正解 T2 「CCO 2017」专业网络 题目 考场思路 题解 T3 「ZJOI2017」线段树 题目 考场思路 正解 这场考试感觉很奇怪. \(T1.T2\) ...

  9. 「2018-11-05模拟赛」T5 传送机 解题报告

    5.传送机(sent.*) 问题描述: 黄黄同学要到清华大学上学去了.黄黄同学很喜欢清华大学的校园,每次去上课时总喜欢把校园里面的每条路都走一遍,当然,黄黄同学想每条路也只走一遍. 我们一般人很可能对 ...

随机推荐

  1. 设计模式----行为型模式之观察者模式(Observer Pattern)

    下面是阅读<Head First设计模式>的笔记. 观察者模式 定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. JDK API内置机制 ...

  2. k8s运维记 - 如何让部署到k8s的kong网关托管自定义静态资源?

    目的 使用kong作为目录/data/reports的静态资源服务器,为了测试,已于目录/data/reports下创建文件report.html,如下: <html> <head& ...

  3. selenium-webdriver中的显式等待与隐式等待

    在selenium-webdriver中等待的方式简单可以概括为三种: 1 导入time包,调用time.sleep()的方法传入时间,这种方式也叫强制等待,固定死等一个时间 2 隐式等待,直接调用i ...

  4. 【JZOJ4807】破解

    Description 历经千辛万苦,ddddddpppppp 终于找到了IBN5100. dp 事先了解到SERN 共有T 个密码,每个密码是一个长度为N 的01 串,他要利用IBN5100 的特殊 ...

  5. Vue学习系列(二)——组件详解

    前言 在上一篇初识Vue核心中,我们已经熟悉了vue的两大核心,理解了Vue的构建方式,通过基本的指令控制DOM,实现提高应用开发效率和可维护性.而这一篇呢,将对Vue视图组件的核心概念进行详细说明. ...

  6. procdump64+mimikatz获取win用户hash密码

    1.导出lsass.exe procdump64.exe -accepteula -ma lsass.exe lsass.dmp 2.执行mimikatz mimikatz.exe "sek ...

  7. [BZOJ5280] [Usaco2018 Open]Milking Order

    Description Farmer John的N头奶牛(1≤N≤105),仍然编号为1…N,正好闲得发慌.因此,她们发展了一个与Farmer John每 天早上为她们挤牛奶的时候的排队顺序相关的复杂 ...

  8. Go 零基础 30 min 入门

        不知不觉用 Go 开发也两年多了. 筹备点经验汇总, 方便后面的同学能快速上手.  提纲     1. Go 安装     2. Go ide 搭建     3. Go modules 模块管 ...

  9. 在VS2013下配置BOOST库

    1.安装Boost库 (1).首先打开Boost的官网(http://www.boost.org/),找到下载位置,如下图中红框所示,此时最新的版本是1.64.0: (2).点击进入下载页面,选择你需 ...

  10. Halcon一日一练:获取程序运行时间

    很多时候,我们需要知道每个函数的运算周期,以提高程序的运行效率.知道运行时间对于图像算法处理很重要 Halcon提供相关的算子,我们先来看代码: **获取图像处理时间 read_image(Image ...