题目分析:

我记得很久以前有人跟我说NOIP2016的题目出了加强版在清华集训中,但这似乎是一道无关的题目?

由于$k$为素数,那么$lucas$定理就可以搬上台面了。

注意到$\binom{i}{j} \equiv 0 {\mod k}$当且仅当将$i$和$j$用$k$进制表示的时候,有一位上的$i<j$。

位数上的计算用数位DP就没错了。

代码:

 #include<bits/stdc++.h>
using namespace std; const int mod = ; int t,k;
long long n,m; int bn[],n1,n2,bm[],nw[]; int f[][][]; //0 0~k-1 1 0~self
int sum[][],pw[],dd[],oo[],fw[],yw[]; void init(){
if(n < m) m = n;
memset(bn,,sizeof(bn)); memset(bm,,sizeof(bm)); n1 = ,n2 = ;
long long p1 = n,p2 = m;
while(p1){bn[++n1] = p1 % k; p1 /= k;}
while(p2){bm[++n2] = p2 % k; p2 /= k;}
dd[] = ;oo[] = ;
for(int i=;i<=n1;i++) dd[i] = (dd[i-] + 1ll*bm[i]*pw[i-]%mod)%mod;
for(int i=;i<=n1;i++) oo[i] = (oo[i-] + 1ll*bn[i]*pw[i-]%mod)%mod;
} pair<int,int> dfs3(int now){
if(now == ){return make_pair(,);}
int ans1 = ,ans2 = ;
pair<int,int> pt = dfs3(now-);
int cutp = min(bn[now]+,bm[now]);
for(int i=;i<bn[now];i++){
int cuep = min(i+,bm[now]);
ans1 += (1ll*cuep*sum[now-][])%mod; ans1 %= mod;
ans1 += (1ll*(bm[now]-cuep)*pw[now-])%mod*pw[now-]%mod;ans1%=mod;
if(bm[now] > i){ans1 += (1ll*pw[now-]*dd[now-])%mod; ans1 %= mod;}
else{ans1 += nw[now-];ans1 %= mod;}
ans2 += (1ll*(i+)*sum[now-][])%mod; ans2 %= mod;
ans2 += (1ll*(k-i-)*pw[now-]%mod*pw[now-])%mod; ans2 %= mod;
}
ans1 += (1ll*cutp*pt.second)%mod; ans1 %= mod;
ans1 += (1ll*(bm[now]-cutp)*oo[now-]%mod*pw[now-])%mod;ans1 %= mod;
if(bm[now] > bn[now]){ans1 += (1ll*oo[now-]*dd[now-])%mod;ans1%=mod;}
else{ans1 += pt.first;ans1 %= mod;}
ans2 += (1ll*(bn[now]+)*pt.second)%mod; ans2 %= mod;
ans2 += (1ll*(k-bn[now]-)*oo[now-])%mod*pw[now-]%mod;ans2 %= mod;
return make_pair(ans1,ans2);
} void work(){
memset(f,,sizeof(f));memset(sum,,sizeof(sum));memset(nw,,sizeof(nw));
for(int i=;i<=n1;i++){
for(int j=;j<k;j++){
f[i][j][] = (1ll*j*sum[i-][]+sum[i-][]+f[i][j][])%mod;
f[i][j][] += (1ll*(j+)*sum[i-][])%mod; f[i][j][] %= mod;
f[i][j][] += (1ll*(k-j-)*((1ll*pw[i-]*pw[i-])%mod))%mod;
f[i][j][] %= mod;
sum[i][] += f[i][j][]; sum[i][] %= mod;
sum[i][] += f[i][j][]; sum[i][] %= mod;
}
}
int ans = ;
for(int now=;now<=n1;now++){
int ans1 = ,ans2 = ;
for(int i=;i<bm[now];i++){
ans1 = (ans1 + 1ll*sum[now-][]*(i+))%mod;
ans1 +=(1ll*pw[now-]*pw[now-])%mod*(bm[now]--i)%mod;ans1%=mod;
ans1 += (1ll*pw[now-]*dd[now-])%mod; ans1 %= mod;
ans2 += (1ll*(i+)*sum[now-][])%mod; ans2 %= mod;
ans2 += ((1ll*(k-i-)*pw[now-])%mod*pw[now-])%mod; ans2 %= mod;
}
ans2 = (ans2+1ll*yw[now-]*(bm[now]+))%mod;
ans2+=((1ll*pw[now-]*(k-bm[now]-))%mod*dd[now-])%mod;ans2%=mod;
ans1 = (1ll*yw[now-]*bm[now]+fw[now-]+ans1)%mod;
fw[now] = ans1; yw[now] = ans2;
}
for(int now=;now<=n1;now++){
for(int i=;i<bm[now];i++){
nw[now] += (1ll*pw[now-]*i%mod*pw[now-])%mod; nw[now] %= mod;
nw[now] = (nw[now]+1ll*(k-i)*sum[now-][])%mod;
}
nw[now] += 1ll*bm[now]*pw[now-]%mod*dd[now-]%mod; nw[now] %= mod;
nw[now] = (nw[now]+1ll*(k-bm[now])*nw[now-])%mod;
}
ans += fw[n1];ans-=(m%mod*((m+)%mod)/2ll)%mod; if(ans < ) ans += mod;
pair<int,int> ans2 = dfs3(n1);
ans = ans + (ans2.first-fw[n1]); ans %= mod; ans += mod; ans %= mod;
printf("%d\n",ans);
} int main(){
scanf("%d%d",&t,&k);
pw[] = ; for(int i=;i<=;i++) pw[i] = (1ll*pw[i-]*k)%mod;
while(t--){
scanf("%lld%lld",&n,&m);
init(); work();
}
return ;
}

UOJ275 [清华集训2016] 组合数问题 【Lucas定理】【数位DP】的更多相关文章

  1. uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT)

    uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT) uoj 题目描述自己看去吧( 题解时间 首先看到 $ p $ 这么小还是质数,第一时间想到 $ lucas $ 定理. 注意 ...

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

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

  3. BZOJ4737 组合数问题 【Lucas定理 + 数位dp】

    题目 组合数C(n,m)表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3)三个物品中选择两个物品可以有( 1,2),(1,3),(2,3)这三种选择方法.根据组合数的定义,我们可以给 ...

  4. bzoj 1902: Zju2116 Christopher lucas定理 && 数位DP

    1902: Zju2116 Christopher Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 172  Solved: 67[Submit][Stat ...

  5. uoj#268. 【清华集训2016】数据交互(动态dp+堆)

    传送门 动态dp我好像还真没咋做过--通过一个上午的努力光荣的获得了所有AC的人里面的倒数rk3 首先有一个我一点也不觉得显然的定理,如果两条路径相交,那么一定有一条路径的\(LCA\)在另一条路径上 ...

  6. UOJ 275. 【清华集训2016】组合数问题

    UOJ 275. [清华集训2016]组合数问题 组合数 $C_n^m $表示的是从 \(n\) 个物品中选出 \(m\) 个物品的方案数.举个例子,从$ (1,2,3)(1,2,3)$ 三个物品中选 ...

  7. UOJ #269. 【清华集训2016】如何优雅地求和

    UOJ #269. [清华集训2016]如何优雅地求和 题目链接 给定一个\(m\)次多项式\(f(x)\)的\(m+1\)个点值:\(f(0)\)到\(f(m)\). 然后求: \[ Q(f,n,x ...

  8. UOJ #274. 【清华集训2016】温暖会指引我们前行 [lct]

    #274. [清华集训2016]温暖会指引我们前行 题意比较巧妙 裸lct维护最大生成树 #include <iostream> #include <cstdio> #incl ...

  9. UOJ_274_[清华集训2016]温暖会指引我们前行_LCT

    UOJ_274_[清华集训2016]温暖会指引我们前行_LCT 任务描述:http://uoj.ac/problem/274 本题中的字典序不同在于空串的字典序最大. 并且题中要求排序后字典序最大. ...

随机推荐

  1. NLP之——Word2Vec详解

    2013年,Google开源了一款用于词向量计算的工具--word2vec,引起了工业界和学术界的关注.首先,word2vec可以在百万数量级的词典和上亿的数据集上进行高效地训练:其次,该工具得到的训 ...

  2. 小记Java时间工具类

    小记Java时间工具类 废话不多说,这里主要记录以下几个工具 两个时间只差(Data) 获取时间的格式 格式化时间 返回String 两个时间只差(String) 获取两个时间之间的日期.月份.年份 ...

  3. for 循环 以及基本的数据类型

    for 循环: for 关键字 i 变量(此处可以更改 更改规则参考变量命名规则) in 关键字 可迭代对象 (想要循环谁就放谁,注意:数字除外 因为数字不可迭代) for 循环内可以进行任意操作,可 ...

  4. DOM操作 JS事件 节点增删改查

    --------------------------习惯是社会的巨大的飞轮和最可贵的维护者.——威·詹姆斯 day 49 [value属性操作] <!DOCTYPE html><ht ...

  5. portscaner 多线程、多协程并发端口扫描

    import socket,time,re,sys,os,threading import gevent from gevent import monkey monkey.patch_all() so ...

  6. c语言之sizeof的细节

    关于sizeof,我们知道sizeof并不是一个函数,尽管通常我们会用sizeof()用法(这是c语言的坑),在此关于sizeof的一些关键不被认知的进行一下总结: # include "i ...

  7. IOS-43-导航栏标题navigationItem.title不能改变颜色的两种解决方法

    IOS-43-导航栏标题navigationItem.title不能改变颜色的两种解决方法 IOS-43-导航栏标题navigationItem.title不能改变颜色的两种解决方法 两种方法只是形式 ...

  8. Linux之磁盘挂载

    1.查看磁盘分区情况: fdisk -l 可以看到,红框中的硬盘没有分区. 2.开始分区: fdisk /dev/vdb 3.格式化分区: mkfs.xfs 分区名 4.挂载磁盘 挂载方式1: 手动挂 ...

  9. Spring配置文件beans.xml头部配置解释

    Spring配置文件beans.xml头部配置解释 - EasonJim - 博客园https://www.cnblogs.com/EasonJim/p/6880329.html

  10. Proper usage of Java -D command-line parameters

    https://stackoverflow.com/questions/5045608/proper-usage-of-java-d-command-line-parameters https://c ...