UOJ275 [清华集训2016] 组合数问题 【Lucas定理】【数位DP】
题目分析:
我记得很久以前有人跟我说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】的更多相关文章
- uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT)
uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT) uoj 题目描述自己看去吧( 题解时间 首先看到 $ p $ 这么小还是质数,第一时间想到 $ lucas $ 定理. 注意 ...
- [BZOJ4591][SHOI2015]超能粒子炮·改(Lucas定理+数位DP)
大组合数取模可以想到Lucas,考虑Lucas的意义,实际上是把数看成P进制计算. 于是问题变成求1~k的所有2333进制数上每一位数的组合数之积. 数位DP,f[i][0/1]表示从高到低第i位,这 ...
- BZOJ4737 组合数问题 【Lucas定理 + 数位dp】
题目 组合数C(n,m)表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3)三个物品中选择两个物品可以有( 1,2),(1,3),(2,3)这三种选择方法.根据组合数的定义,我们可以给 ...
- bzoj 1902: Zju2116 Christopher lucas定理 && 数位DP
1902: Zju2116 Christopher Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 172 Solved: 67[Submit][Stat ...
- uoj#268. 【清华集训2016】数据交互(动态dp+堆)
传送门 动态dp我好像还真没咋做过--通过一个上午的努力光荣的获得了所有AC的人里面的倒数rk3 首先有一个我一点也不觉得显然的定理,如果两条路径相交,那么一定有一条路径的\(LCA\)在另一条路径上 ...
- UOJ 275. 【清华集训2016】组合数问题
UOJ 275. [清华集训2016]组合数问题 组合数 $C_n^m $表示的是从 \(n\) 个物品中选出 \(m\) 个物品的方案数.举个例子,从$ (1,2,3)(1,2,3)$ 三个物品中选 ...
- UOJ #269. 【清华集训2016】如何优雅地求和
UOJ #269. [清华集训2016]如何优雅地求和 题目链接 给定一个\(m\)次多项式\(f(x)\)的\(m+1\)个点值:\(f(0)\)到\(f(m)\). 然后求: \[ Q(f,n,x ...
- UOJ #274. 【清华集训2016】温暖会指引我们前行 [lct]
#274. [清华集训2016]温暖会指引我们前行 题意比较巧妙 裸lct维护最大生成树 #include <iostream> #include <cstdio> #incl ...
- UOJ_274_[清华集训2016]温暖会指引我们前行_LCT
UOJ_274_[清华集训2016]温暖会指引我们前行_LCT 任务描述:http://uoj.ac/problem/274 本题中的字典序不同在于空串的字典序最大. 并且题中要求排序后字典序最大. ...
随机推荐
- Python-类与对象
类与对象的概念 类即类别.种类,是面向对象设计最重要的概念,从一小节我们得知对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体. 那么问题来了,先有的一个个具体存在的对象(比如一个具 ...
- rest-framework频率组件
throttle(访问频率)组件 1.局部视图throttle from rest_framework.throttling import BaseThrottle VISIT_RECORD={} c ...
- 软件工程(FZU2015) 赛季得分榜,第七回合
SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分=团队得分+个人贡献分 个人贡献分: 个人 ...
- 什么是IaaS, PaaS和SaaS及其区别
IaaS, PaaS和SaaS是云计算的三种服务模式. . SaaS:Software-as-a-Service(软件即服务)提供给客户的服务是运营商运行在云计算基础设施上的应用程序,用户可以在各种设 ...
- linux的nohup命令
linux的nohup命令的用法. - runfox545 - 博客园https://www.cnblogs.com/allenblogs/archive/2011/05/19/2051136.htm ...
- Linux下用rm删除的文件的恢复方法
Linux下用rm删除的文件的恢复方法_Linux教程_Linux公社-Linux系统门户网站https://www.linuxidc.com/Linux/2008-08/14744.htm linu ...
- Docker : Tomcat Clustering with Load Balancer (Tomcat and Nginx)
Tomcat Clustering Series Part 5 : NginX as Load Balancer - Ramki Technical Bloghttps://www.ramkitech ...
- vue单页面模板说明文档(1)
Introduction This boilerplate is targeted towards large, serious projects and assumes you are somewh ...
- spring boot中的约定优于配置
Spring Boot并不是一个全新的框架,而是将已有的Spring组件整合起来. Spring Boot可以说是遵循约定优于配置这个理念产生的.它的特点是简单.快速和便捷. 既然遵循约定优于配置,则 ...
- RedHat Enterprise Linux 6.4使用yum安装出现This system is not registered to Red Hat Subscription Management
我虚拟机安装的系统是RedHat Enterprise Linux 6.4-i686,是32位的.使用yum命令安装软件时候出现以下错误: This system is not registered ...