[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=2425

[算法]

类似与数位动态规划的思想 , 用组合数学进行简单推导即可

时间复杂度 : O(L ^ 3)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define N 110
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; #define int ll int L , L0;
int tmp[N] , digit[N] , cnt[N];
char s[N]; template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline ll quickpow(ll a , int n)
{
ll b = a , res = ;
while (n > )
{
if (n & ) res *= b;
b = b * b;
n >>= ;
}
return res;
}
inline void add(int x , int val)
{
for (int i = ; i <= (int)sqrt(x); i++)
{
if (x % i == )
{
while (x % i == )
{
tmp[i] += val;
x /= i;
}
}
}
if (x > ) tmp[x] += val;
} signed main()
{ scanf("%s" , s + );
L = strlen(s + );
for (int i = ; i <= L; i++)
{
if (s[i] > '') ++L0;
++cnt[s[i] - ''];
digit[i] = s[i] - '';
}
ll ans = ;
for (int k = ; k < L;k++)
{
if (k < L0) continue;
memset(tmp , , sizeof(tmp));
for (int i = ; i <= L0; i++) add(i , );
for (int i = ; i <= ; i++)
{
for (int j = ; j <= cnt[i]; j++)
{
add(j , -);
}
}
for (int i = ; i <= k - ; i++) add(i , );
for (int i = ; i <= L0 - ; i++) add(i , -);
for (int i = ; i <= k - L0; i++) add(i , -);
ll cont = ;
for (int i = ; i <= ; i++) cont *= quickpow(i , tmp[i]);
ans += cont;
}
for (int i = ; i <= L; i++)
{
for (int j = ; j < digit[i]; j++)
{
if (i == && !j) continue;
if (!j || cnt[j] > )
{
--cnt[j];
int nowcnt = ;
for (int k = ; k <= ; k++) nowcnt += cnt[k];
if (nowcnt > L - i)
{
++cnt[j];
continue;
}
memset(tmp , , sizeof(tmp));
for (int k = ; k <= nowcnt; k++) add(k , );
for (int x = ; x <= ; x++)
{
for (int y = ; y <= cnt[x]; y++)
{
add(y , -);
}
}
for (int k = ; k <= L - i; k++) add(k , );
for (int k = ; k <= nowcnt; k++) add(k , -);
for (int k = ; k <= L - i - nowcnt; k++) add(k , -);
ll cont = ;
for (int k = ; k <= ; k++) cont *= quickpow(k , tmp[k]);
ans += cont;
++cnt[j];
}
}
--cnt[digit[i]];
}
printf("%lld\n" , ans); return ;
}

最新文章

  1. web前端基础知识-(七)Django进阶
  2. s2 devMode cmdshell
  3. VUE 入门基础(5)
  4. UML简介
  5. js中的this关键字详解
  6. windows 命令修改IP
  7. MCS-51系统中断优先级的软扩展
  8. JS 代码调试经验总结(菜鸟必读)
  9. QT 自动获取可用串口
  10. DB2函数大全
  11. Android Realm数据库使用指南
  12. 对vuex的认识和简单理解
  13. MongoDB之 分组查询
  14. ansj分词
  15. 用矩阵和待定系数法求数列的分析(复杂度log(n))
  16. RabbitMQ(二):Java 操作队列
  17. 模拟spring的IoC
  18. H5活动页面与APP交互规则
  19. (笔记)Mysql命令use:使用数据库
  20. sqlite3错误码整理

热门文章

  1. HBase 基本操作
  2. DNS 域名解析过程
  3. ffmpeg h264编码 extradata 为空
  4. LINUXFOUNDATION EVENTS
  5. 学习某些API的方法
  6. Colly provides a clean interface to write any kind of crawler/scraper/spider
  7. Part of defining a topology is specifying for each bolt which streams it should receive as input
  8. ajax json html 结合
  9. Linux struct itimerval使用方法
  10. XMPP学习笔记 -- RFC 6120