传送门


模数小,还是个质数,Lucas没得跑

考虑Lucas的实质。设\(a = \sum\limits_{i=0}^5 a_i 2333^i\),\(b = \sum\limits_{i=0}^5 b_i2333^i\),那么\(C_a^b \mod2333 = \prod\limits_{i=0}^5 C_{a_i}^{b_i} \mod 2333\)

可以认为Lucas就是将\(a,b\)两个数化成\(2333\)进制数之后每一位组合运算的乘积。似乎与数位相关,使用类似于数位DP的思考方式,从高到低填数。

因为现在需要求的是\(\sum\limits_{i=0}^k C_n^i\),假设\(k\)在\(2333\)进制下表示为\(\overline {k_5k_4k_3k_2k_1k_0}\),\(n\)在\(2333\)进制下表示为\(\overline{n_5n_4n_3n_2n_1n_0}\),那么对于第\(5\)位\(< k_5\)的数,后面的四位一定会取到\(0\)到\(2332\)的所有值。我们处理出\(\prod \limits _{i=0}^4 \sum\limits_{j=0}^{2332} C_{n_i}^j\),根据二项式定理这其实就是\(2^{n_0+n_1+n_2+n_3+n_4}\),那么\(2333\)进制下第\(5\)位\(<k_5\)的所有数的贡献就是\(2^{n_0+n_1+n_2+n_3+n_4}\sum\limits_{i=0}^{k_5-1}C_{n_5}^i\)。

最后考虑第\(5\)位等于\(k_5\)的情况,在这种情况下接着考虑第\(4\)位,方式跟上面一致,不断做下去直到所有位都被考虑完。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<vector>
#include<cmath>
#define ll long long
//This code is written by Itst
using namespace std; inline ll read(){
ll a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c) && c != EOF){
if(c == '-')
f = 1;
c = getchar();
}
if(c == EOF)
exit(0);
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return f ? -a : a;
} const int MOD = 2333;
int C[MOD][MOD] , inv[MOD] , sum[6] , mod[6];
ll powM[6]; inline int poww(int a , int b){
int times = 1;
while(b){
if(b & 1)
times = times * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return times;
} int calc(ll cur , int now){
if(now < 0)
return 1;
if(cur / powM[now])
return (C[mod[now]][cur / powM[now] - 1] * sum[now] + (C[mod[now]][cur / powM[now]] - C[mod[now]][cur / powM[now] - 1] + MOD) * calc(cur % powM[now] , now - 1)) % MOD;
return calc(cur , now - 1);
} void init(){
powM[0] = sum[0] = 1;
for(int i = 1 ; i <= 5 ; ++i)
powM[i] = powM[i - 1] * MOD;
C[0][0] = 1;
for(int i = 1 ; i < MOD ; ++i){
C[i][0] = 1;
for(int j = 1 ; j < MOD ; ++j)
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
}
for(int i = 0 ; i < MOD ; ++i)
for(int j = 1 ; j < MOD ; ++j)
C[i][j] = (C[i][j] + C[i][j - 1]) % MOD;
} signed main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
freopen("out","w",stdout);
#endif
init();
for(int T = read() ; T ; --T){
ll N = read() , K = read();
for(int i = 1 ; i <= 5 ; ++i){
mod[i - 1] = N / powM[i - 1] % 2333;
sum[i] = poww(2 , mod[i - 1]) * sum[i - 1] % MOD;
}
mod[5] = N / powM[5];
cout << calc(K , 5) << '\n';
}
return 0;
}

Luogu4345 SHOI2015 超能粒子炮·改 Lucas、数位DP的更多相关文章

  1. bzoj 4591: [Shoi2015]超能粒子炮·改 [lucas定理]

    4591: [Shoi2015]超能粒子炮·改 题意:多组询问,求 \[ S(n, k) = \sum_{i=0}^n \binom{n}{i} \mod 2333,\ k \le n \le 10^ ...

  2. 【bzoj4591】[Shoi2015]超能粒子炮·改 Lucas定理

    题目描述 曾经发明了脑洞治疗仪&超能粒子炮的发明家SHTSC又公开了他的新发明:超能粒子炮·改--一种可以发射威力更加强大的粒子流的神秘装置.超能粒子炮·改相比超能粒子炮,在威力上有了本质的提 ...

  3. P4345 [SHOI2015]超能粒子炮·改 Lucas

    \(\color{#0066ff}{ 题目描述 }\) 曾经发明了脑洞治疗仪与超能粒子炮的发明家 SHTSC 又公开了他的新发明:超能粒子炮・改--一种可以发射威力更加强大的粒子流的神秘装置. 超能粒 ...

  4. [bzoj4591][Shoi2015][超能粒子炮·改] (lucas定理+组合计数)

    Description 曾经发明了脑洞治疗仪&超能粒子炮的发明家SHTSC又公开了他的新发明:超能粒子炮·改--一种可以发射威力更加 强大的粒子流的神秘装置.超能粒子炮·改相比超能粒子炮,在威 ...

  5. [BZOJ4591][SHOI2015]超能粒子炮·改(Lucas定理+数位DP)

    大组合数取模可以想到Lucas,考虑Lucas的意义,实际上是把数看成P进制计算. 于是问题变成求1~k的所有2333进制数上每一位数的组合数之积. 数位DP,f[i][0/1]表示从高到低第i位,这 ...

  6. luogu4345 [SHOI2015]超能粒子炮·改(组合数/Lucas定理)

    link 输入\(n,k\),求\(\sum_{i=0}^k{n\choose i}\)对2333取模,10万组询问,n,k<=1e18 注意到一个2333这个数字很小并且还是质数这一良好性质, ...

  7. Bzoj 4591: [Shoi2015]超能粒子炮·改 数论,Lucas定理,排列组合

    4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 178  Solved: 70[Submit][Stat ...

  8. Lucas(卢卡斯)定理模板&&例题解析([SHOI2015]超能粒子炮·改)

    Lucas定理 先上结论: 当p为素数: \(\binom{ N }{M} \equiv \binom{ N/p }{M/p}*\binom{ N mod p }{M mod p} (mod p)\) ...

  9. bzoj4591 / P4345 [SHOI2015]超能粒子炮·改

    P4345 [SHOI2015]超能粒子炮·改 题意:求$\sum_{i=1}^{k}C(n,i)\%(P=2333)$ 肯定要先拆开,不然怎么做呢(大雾) 把$C(n,i)$用$lucas$分解一下 ...

随机推荐

  1. float清除浮动

    清除浮动: 在非IE浏览器下,当容器的高度为auto,且容器的内容中有浮动(float为left或right)的元素,在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外面而影响 ...

  2. jquery制作移动端菜单栏左右滑动

    //菜单栏滑动function move_scollX(){ var startPosition, endPosition, distanceX,distanceY; $(".left&qu ...

  3. base64加密和解码原理和代码

    Base64编码,是我们程序开发中经常使用到的编码方法.它是一种基于用64个可打印字符来表示二进制数据的表示方法.它通常用作存储.传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用 ...

  4. Linux 学习笔记之超详细基础linux命令 Part 12

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 11---------------- ...

  5. linux中使用nfs共享文件

    NFS需要使用远程过程调用 (RPC),也就是说,我们并不是只要启动NFS, 还需要启动RPC这个服务 服务器端 CentOS 7.4 ip:172.16.0.1 共享/tmp目录 共享/data目录 ...

  6. centos7安装rabbitmq 总结

    centos7下安装rabbitmq 折腾了三天最后做了以下总结 先查看一电脑名  :示例 #hostname name 查看一下hosts配置文件:如果如下结果,就要修改下 #cat /etc/ho ...

  7. OSPF单区域配置

    OSPF单区域配置 实验环境:华为模拟器eNSP 现在有这样一个拓扑图: 我想要让R1可以ping通R3,显然目前是不行的: <R1>ping 192.168.2.2 PING 192.1 ...

  8. css固定背景图位置 实现屏幕滚动时 显示背景图不同区域

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  9. vs2015添加管理员权限

    在工作过程中,我可能可能遇到要求编译好的程序默认以管理员权限运行,我们可以这样操作 一.新建一个manifest文件: <?xml version="1.0" encodin ...

  10. IDEA多线程下多个线程切换断点运行调试的技巧

    多线程调试设置可以参考:http://www.cnblogs.com/leodaxin/p/7710630.html 1 断点设置如图: 2 测试代码,然后进行debug package com.da ...