UOJ #54 时空穿梭 —— 计数+莫比乌斯反演+多项式系数
10分还要用 Lucas 定理囧...因为模数太小了不能直接算...
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
int const xn=1e5+,xm=,mod=;
int n,num,m[xm],jc[xn],jcn[xn];
ll pw(ll a,int b){ll ret=; for(;b;b>>=,a=a*a%mod)if(b&)ret=ret*a%mod; return ret;}
void init()
{
jc[]=; int mx=mod-;
for(int i=;i<=mx;i++)jc[i]=(ll)jc[i-]*i%mod;
jcn[mx]=pw(jc[mx],mod-);
for(int i=mx-;i>=;i--)jcn[i]=(ll)jcn[i+]*(i+)%mod;
}
int C(int n,int m){return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod;}
int lucas(int n,int m)
{
if(m==||n<m)return ;
return (ll)lucas(n/mod,m/mod)*C(n%mod,m%mod)%mod;
}
int upt(int x){while(x>=mod)x-=mod; while(x<)x+=mod; return x;}
int main()
{
int T=rd(); init();
while(T--)
{
n=rd(); num=rd(); bool fl=;
for(int i=;i<=n;i++)
{
m[i]=rd();
if(m[i]>)fl=;
}
if(n==)printf("%d\n",lucas(m[],num));
}
return ;
}
10分
参考博客:https://www.cnblogs.com/ljh2000-jump/p/6242237.html
开头结尾思路好妙,莫比乌斯反演好套路;
忘记前缀和调了半天hhh。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
int Min(int x,int y){return x<y?x:y;}
int const xn=,xm=1e5+,xc=,mod=;
int n,c,m[xn],a[xn],C[xm][xc],G[xc][xm],f[xc][xm][xn],mu[xm],cnt,pri[xm],inv2;
bool vis[xm];
ll pw(ll a,int b){ll ret=; for(;b;b>>=,a=a*a%mod)if(b&)ret=ret*a%mod; return ret;}
int upt(int x){while(x>=mod)x-=mod; while(x<)x+=mod; return x;}
void getpri()
{
int mx=1e5; mu[]=;
for(int i=;i<=mx;i++)
{
if(!vis[i])pri[++cnt]=i,mu[i]=-;
for(int j=;j<=cnt&&(ll)i*pri[j]<=mx;j++)
{
vis[i*pri[j]]=;
if(i%pri[j])mu[i*pri[j]]=-mu[i];
else break;
}
}
}
void init()
{
int mx=1e5;
for(int i=;i<=mx;i++)C[i][]=;
for(int i=;i<=mx;i++)
for(int j=;j<=;j++)
C[i][j]=upt(C[i-][j]+C[i-][j-]);
for(int c=;c<=;c++)
{
for(int g=;g<=mx;g++)
for(int T=g;T<=mx;T+=g)
G[c][T]=upt(G[c][T]+C[g-][c-]*mu[T/g]);
for(int T=;T<=mx;T++)
for(int i=,k=;i<=;i++,k=(ll)k*T%mod)
f[c][T][i]=(f[c][T-][i]+(ll)k*G[c][T])%mod;
}
}
void get(int t)//(px+q)
{
int tmp,p,q;
memset(a,,sizeof a); a[]=;//
for(int i=;i<=n;i++)
{
tmp=m[i]/t;
p=upt(-(ll)tmp*(tmp+)%mod*inv2%mod);
q=(ll)tmp*m[i]%mod;
for(int j=i;j;j--)
a[j]=upt((ll)a[j-]*p%mod+(ll)a[j]*q%mod);
a[]=upt((ll)a[]*q%mod);
}
}
int main()
{
int T=rd(); getpri(); init(); inv2=pw(,mod-);
while(T--)
{
n=rd(); c=rd(); int mn=xm,ans=;
for(int i=;i<=n;i++)m[i]=rd(),mn=Min(mn,m[i]);
for(int i=,nxt;i<=mn;i=nxt+)
{
nxt=m[]/(m[]/i);
for(int j=;j<=n;j++)nxt=Min(nxt,m[j]/(m[j]/i));
get(i);
for(int j=;j<=n;j++)ans=upt(ans+(ll)a[j]*(f[c][nxt][j]-f[c][i-][j])%mod);
}
printf("%d\n",ans);
}
return ;
}
UOJ #54 时空穿梭 —— 计数+莫比乌斯反演+多项式系数的更多相关文章
- BZOJ3434 WC2014时空穿梭(莫比乌斯反演)
考虑枚举相邻点距离差的比例.显然应使比例值gcd为1以保证不重复统计.确定比例之后,各维坐标的方案数就可以分开考虑.设比例之和为k,则若坐标上限为m,该维坐标取值方案数即为Σm-ki (i=1~⌊m/ ...
- 【51nod】1222 最小公倍数计数 莫比乌斯反演+组合计数
[题意]给定a和b,求满足a<=lcm(x,y)<=b && x<y的数对(x,y)个数.a,b<=10^11. [算法]莫比乌斯反演+组合计数 [题解]★具体 ...
- 51NOD 1222 最小公倍数计数 [莫比乌斯反演 杜教筛]
1222 最小公倍数计数 题意:求有多少数对\((a,b):a<b\)满足\(lcm(a,b) \in [1, n]\) \(n \le 10^{11}\) 卡内存! 枚举\(gcd, \fra ...
- 51nod1222 最小公倍数计数 莫比乌斯反演 数学
求$\sum_{i = 1}^{n} \sum_{j = 1}^{i} [lcm(i, j) \le n]$因为这样不好求,我们改成求$\sum_{i = 1}^{n} \sum_{j = 1}^{n ...
- BZOJ 3518 点组计数 ——莫比乌斯反演
要求$ans=\sum_{i=1}^n \sum_{j=1}^m (n-i)(m-j)(gcd(i,j)-1)$ 可以看做枚举矩阵的大小,然后左下右上必须取的方案数. 这是斜率单增的情况 然后大力反演 ...
- 数学:莫比乌斯反演-GCD计数
Luogu3455:莫比乌斯反演进行GCD计数 莫比乌斯反演就是用来解决这一类问题的,通常f函数是要求的那个,F函数是显然的 这样利用F的结果就可以推出来f的结果 在计算结果的时候整除分快儿一下就可以 ...
- 【BZOJ3434】[Wc2014]时空穿梭 莫比乌斯反演
[BZOJ3434][Wc2014]时空穿梭 Description Input 第一行包含一个正整数T,表示有T组数据求解每组数据包含两行,第一行包含两个正整数N,C(c>=2),分别表示空间 ...
- UOJ#54 BZOJ3434 [WC2014]时空穿梭
题目描述 小 X 驾驶着他的飞船准备穿梭过一个 \(n\) 维空间,这个空间里每个点的坐标可以用 \(n\) 个实数表示,即 \((x_1,x_2,\dots,x_n)\). 为了穿过这个空间,小 X ...
- loj#6076「2017 山东一轮集训 Day6」三元组 莫比乌斯反演 + 三元环计数
题目大意: 给定\(a, b, c\),求\(\sum \limits_{i = 1}^a \sum \limits_{j = 1}^b \sum \limits_{k = 1}^c [(i, j) ...
随机推荐
- uva 12086 线段树or树状数组练习
题目链接 https://vjudge.net/problem/34215/origin 这个题就是线段树裸题,有两种操作,实现单点更新和区间和的查找即可,这里第一次学习使用树状数组完成. 二者相 ...
- field字段错位手动更改方法
update tbprotocolex set field='1' where name='ICMP';update tbprotocolex set field='1' where name='DN ...
- 006-对象—— static关键字 静态属性和方法的使用
<?php /*static()静态属性: */ //静态属性: /*class Model{ private $mysqli; static $config;//数据库连接状态 functio ...
- Java复习6异常处理
Java复习6.异常处理 20131005 前言: Java中的异常处理机制是非常强大的,相比C++ 来说,更加系统.但是我们开发人员没有很好的使用这一点.一些小的程序是没有什么问题的,但是对于大型项 ...
- C++进阶1模板的使用
C++进阶1模板的使用 20131010 C++中,我们自己编程虽然不会怎么使用模板,包括函数模板和类模板,但是在大型的项目开发中函数模板和类模板是非常重要的.笔者在**面试的时候忙问道过这个问题,迷 ...
- 内存保护机制及绕过方法——通过伪造SEHOP链绕过SEHOP保护机制
1.1 SEHOP保护机制 1.1.1 SEHOP工作原理: SEHOP保护机制的核心就是检查SEH链的完整性,其验证代码如下: BOOL RtlIsValidHandler(handle ...
- SpringAnnotation之配置AnnotationXML文件
配置Annotation的环境:只需修改applicationContext.xml文件即可 1 2 3 4 5 6 7 8 9 10 11 <?xml version="1.0&qu ...
- MATLAB基础知识tips
网络论坛资源: MATLAB中文论坛https://i.cnblogs.com/EditPosts.aspx?opt=1 circshift 移位函数,circshift(A,SHIFTSIZE).S ...
- Ubuntu与ROS的Docker桌面系统与ROS在线练习课程(在线Linux虚拟机)
ROS在线练习课程正在逐步完善中,目前以ROS官网中文资料制作,可参考: https://www.shiyanlou.com/courses/854 邀请码 U23ERF8H 安装Ubuntu+RO ...
- HAWQ + MADlib 玩转数据挖掘之(五)——奇异值分解实现推荐算法
一.奇异值分解简介 奇异值分解简称SVD(singular value decomposition),可以理解为:将一个比较复杂的矩阵用更小更简单的三个子矩阵的相乘来表示,这三个小矩阵描述了大矩阵重要 ...