各种反演细节梳理&模板
炫酷反演魔术课件byVFK
stO FDF Orz(证明全有%%%)
莫比乌斯反演
\(F(n)=\sum\limits_{d|n}f(d)\Rightarrow f(n)=\sum\limits_{d|n}\mu(\frac n d)F(d)\)
\(F(n)=\sum\limits_{n|d}f(d)\Rightarrow f(n)=\sum\limits_{n|d}\mu(\frac d n)F(d)\)
推带\(\gcd\)的题常用式子:(实际上是借用了积性函数的式子)
\([\gcd(i,j)==1]=\sum\limits_{d|gcd(i,j)}\mu(d)\)
\(gcd(i,j)=\sum\limits_{d|i,d|j}\varphi(d)\)
洛谷P3455 [POI2007]ZAP-Queries
\(f(n)=\sum\limits_{i=1}^a\sum\limits_{j=1}^b[\gcd(i,j)==n]\)
1.老实反演
\(F(n)=\sum\limits_{n|d}f(d)=\lfloor\frac a n\rfloor\lfloor\frac b n\rfloor\)
\(f(n)=\sum\limits_{n|d}\mu(\frac{d}{n})\lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor=\sum\limits_{d=1}^{\lceil\frac{\min(a,b)}{n}\rceil}\mu(d)\lfloor\frac a{nd}\rfloor\lfloor\frac b{nd}\rfloor\)
2.套式子
\(f(n)=\sum\limits_{i=1}^{\lfloor\frac{a}{n}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{b}{n}\rfloor}[\gcd(i,j)==1]=\sum\limits_{d|gcd(i,j)}\sum\limits_{i=1}^{\lfloor\frac{a}{n}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{b}{n}\rfloor}\mu(d)=\sum\limits_{d=1}^{\lfloor\frac{\min(a,b)}{n}\rfloor}\mu(d)\lfloor\frac a{nd}\rfloor\lfloor\frac b{nd}\rfloor\)
整除分块,时间复杂度\(O(\sqrt n)\)。
#include<bits/stdc++.h>
#define LL long long
#define RG register
#define R RG int
#define G if(++ip==ie)if(fread(ip=buf,1,SZ,stdin))
using namespace std;
const int SZ=1<<19,N=50009;
int u[N],pr[N],p;bool f[N];
char buf[SZ],*ie=buf+SZ,*ip=ie-1;
inline int in(){
G;while(*ip<'-')G;
R x=*ip&15;G;
while(*ip>'-'){x*=10;x+=*ip&15;G;}
return x;
}
int main(){
u[1]=f[1]=1;
for(R i=2;i<N;++i){
if(!f[i])u[pr[++p]=i]=-1;
for(R j=1;j<=p&&i*pr[j]<N;++j){
f[i*pr[j]]=1;
if(i%pr[j]==0)break;
u[i*pr[j]]=-u[i];
}
u[i]+=u[i-1];
}
for(R n=in();n;--n){
R a=in(),b=in(),d=in(),lim=min(a,b)/d,ans=0;
for(R l=1,r;l<=lim;l=r+1){
r=min(a/(a/l),b/(b/l));
ans+=(u[r]-u[l-1])*(a/(d*l))*(b/(d*l));
}
printf("%d\n",ans);
}
return 0;
}
洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB
\]
#include<bits/stdc++.h>
#define LL long long
#define RG register
#define R RG int
#define YL 20101009
using namespace std;
const int N=1e7+9;
int p,pr[N/10],mu[N],s[N];bitset<N>np;
inline LL Sum(LL x){
return x*(x+1)%YL*((YL+1)>>1)%YL;
}
LL Calc(R n,R m){
LL ans=0;
for(R d=1,r;d<=n;d=r+1){
r=min(n/(n/d),m/(m/d));
ans=(ans+(s[r]-s[d-1]+YL)*Sum(n/d)%YL*Sum(m/d))%YL;
}
return ans;
}
int main(){
R n,m;LL ans=0;
cin>>n>>m;
if(n>m)swap(n,m);
s[1]=1;
for(R i=2;i<=n;++i){
if(!np[i])pr[++p]=i,mu[i]=-1;
s[i]=(s[i-1]+(LL)i*i%YL*mu[i]+YL)%YL;
for(R j=1;j<=p&&i*pr[j]<=n;++j){
np[i*pr[j]]=1;
if(i%pr[j]==0)break;
mu[i*pr[j]]=-mu[i];
}
}
for(R k=1,r;k<=n;k=r+1){
r=min(n/(n/k),m/(m/k));
ans=(ans+(Sum(r)-Sum(k-1)+YL)*Calc(n/k,m/k))%YL;
}
cout<<ans<<endl;
return 0;
}
然鹅BZOJ的JZPTAB有多次询问咋办?
详细题解by hbyer
有一个新的套路:枚举重复出现的\(kd\)(令其为\(t\))
\]
后面那个\(\sum_{d|t}td\mu(d)\)看成关于\(t\)的函数,暴力推一推发现是个积性函数,筛一下就好了。
洛谷P3704 [SDOI2017]数字表格
跟上一题一样的套路
\]
中间那块预处理前缀积,外面数论分块即可。
二项式反演
不常用但是好看:\(f(n)=\sum\limits_{i=0}^n(-1)^i\binom{n}{i}g(i)\Rightarrow g(n)=\sum\limits_{i=0}^n(-1)^i\binom{n}{i}f(i)\)
正好难算,至多好算:\(f(n)=\sum\limits_{i=0}^n\binom{n}{i}g(i)\Rightarrow g(n)=\sum\limits_{i=0}^n(-1)^{n-i}\binom{n}{i}f(i)\)
正好难算,至少好算:\(f(k)=\sum\limits_{i=k}^n\binom{i}{k}g(i)\Rightarrow g(k)=\sum\limits_{i=k}^n(-1)^{i-k}\binom{i}{k}f(i)\)
错排
设\(f(n)\)为至多\(n\)元素错排方案数也就是全排列方案数\(n!\),\(g(n)\)为\(n\)元素错排方案数。
通过枚举排列中错位的元素个数\(i\),有\(f(n)=\sum\limits_{i=0}^n\binom{n}{i}g(i)\)。
直接套第二个式子即可得\(g(n)=\sum\limits_{i=0}^n(-1)^{n-i}\binom{n}{i}f(i)=n!\sum\limits_{i=0}^n(-1)^i\frac{1}{i!}\)
又一个例题
洛谷P4859 已经没有什么好害怕的了
套第三个式子。然并卵关键要想到如何DP和转化
#include<bits/stdc++.h>
#define LL long long
#define RG register
#define R RG int
using namespace std;
const LL N=2009,YL=1e9+9;
int a[N],b[N],ff[N],gg[N],F[N],I[N];
int Pow(LL b,R k,LL a=1){
for(;k;k>>=1,b=b*b%YL)
if(k&1)a=a*b%YL;
return a;
}
int main(){
R n,k,ans=0,*f=ff,*g=gg;
cin>>n>>k;k=(n+k)/2;
for(R i=1;i<=n;++i)cin>>a[i];
for(R i=1;i<=n;++i)cin>>b[i];
sort(a+1,a+n+1);
sort(b+1,b+n+1);
f[0]=g[0]=F[0]=1;
for(R i=1;i<=n;++i){
R pos=lower_bound(b+1,b+n+1,a[i])-b-1;
for(R j=1;j<=i;++j)
g[j]=(f[j]+(LL)f[j-1]*max(pos-j+1,0))%YL;
swap(f,g);
}
for(R i=1;i<=n;++i)F[i]=(LL)F[i-1]*i%YL;
I[n]=Pow(F[n],YL-2);
for(R i=n;i;--i)I[i-1]=(LL)I[i]*i%YL;
for(R i=k;i<=n;++i)
ans=(ans+(LL)((i-k)&1?YL-1:1)*F[i]%YL*I[k]%YL*I[i-k]%YL*F[n-i]%YL*f[i])%YL;
cout<<ans<<endl;
return 0;
}
斯特林反演
十分像二项式反演。。。
正好难算,至多好算:\(f(n)=\sum\limits_{i=0}^nS(n,i)g(i)\Rightarrow g(n)=\sum\limits_{i=0}^n(-1)^{n-i}s(n,i)f(i)\)
正好难算,至少好算:\(f(k)=\sum\limits_{i=k}^nS(i,k)g(i)\Rightarrow g(k)=\sum\limits_{i=k}^n(-1)^{i-k}s(i,k)(i)\)
BZOJ4671 异或图
套第二个式子。然并卵关键要想到子集划分计数和线性基
完整题解:stO yyb Orz
#include<bits/stdc++.h>
#define LL long long
#define RG register
#define R RG int
using namespace std;
const int S=69,N=19;
char str[S];bool g[S][N][N];
int s,n,c[N];
LL ans,lb[S],fac[N];
void calc(R t){
R cnt=0;memset(lb,0,sizeof(lb));
for(R k=1;k<=s;++k){
R p=0;LL now=0;
for(R i=1;i<=n;++i)
for(R j=i+1;j<=n;++j)
if(c[i]!=c[j])now|=(LL)g[k][i][j]<<p++;
for(R i=0;i<p;++i)
if(1ll<<i&now){
if(lb[i])now^=lb[i];
else{lb[i]=now;++cnt;break;}
}
}
ans+=(1&t?1:-1)*fac[t-1]*(1ll<<(s-cnt));
}
void dfs(R x,R t){
if(x>n)return calc(t-1);
for(R&i=c[x]=1;i<=t;++i)dfs(x+1,t+(t==i));
}
int main(){
cin>>s;
for(R k=1;k<=s;++k){
cin>>str;n=(1+sqrt(1+8*strlen(str)))/2;
for(R i=1,p=0;i<=n;++i)
for(R j=i+1;j<=n;++j)
g[k][i][j]=str[p++]&1;
}
for(R i=fac[0]=1;i<=n;++i)fac[i]=fac[i-1]*i;
dfs(1,1);
cout<<ans<<endl;
return 0;
}
最值反演(min-max容斥)
\(\max\{S\}=\sum\limits_{T\subseteq S}(-1)^{|T|+1}\min\{T\}\)
\(\min\{S\}=\sum\limits_{T\subseteq S}(-1)^{|T|+1}\max\{T\}\)
在期望意义下仍然成立,即
\(E(\max\{S\})=\sum\limits_{T\subseteq S}(-1)^{|T|+1}E(\min\{T\})\)
\(E(\min\{S\})=\sum\limits_{T\subseteq S}(-1)^{|T|+1}E(\max\{T\})\)
推广到求第\(k\)大,只有大小\(\ge k\)的子集产生贡献
\(\max_k\{S\}=\sum\limits_{T\subseteq S}(-1)^{|T|-k}\binom{|T|-1}{k-1}\min\{T\}\)
\(\min_k\{S\}=\sum\limits_{T\subseteq S}(-1)^{|T|-k}\binom{|T|-1}{k-1}\max\{T\}\)
洛谷P3175 [HAOI2015]按位或
裸题,FWT之后套第三个式子即可
#include<bits/stdc++.h>
#define R register int
using namespace std;
double EPS=1e-10,a[1<<20];
int c[1<<20];
int main(){
R n,m,s=0;
cin>>n;m=1<<n;
for(R i=0;i<m;++i){
cin>>a[i];
if(a[i]>EPS)s|=i;
c[i]=c[i>>1]^(1&i);
}
if(s!=m-1)return puts("INF"),0;
for(R i=1;i<m;i<<=1)
for(R j=0;j<m;j+=i<<1)
for(R k=0;k<i;++k)
a[k+j+i]+=a[k+j];
double ans=0;
for(R i=1;i<m;++i)
if(a[i]>EPS)ans+=(c[i]?1:-1)/(1-a[i^(m-1)]);
return printf("%.10lf\n",ans),0;
}
洛谷P4707 重返现世
套第五个式子,然并卵关键要想到如何DP出容斥系数
#include<bits/stdc++.h>
#define LL long long
#define RG register
#define R RG int
#define G if(++ip==ie)if(fread(ip=buf,1,SZ,stdin))
using namespace std;
const int SZ=1<<19,N=10009,YL=998244353;
char buf[SZ],*ie=buf+SZ,*ip=ie-1;
int f[N][12];LL inv[N];
inline int in(){
G;while(*ip<'-')G;
R x=*ip&15;G;
while(*ip>'-'){x*=10;x+=*ip&15;G;}
return x;
}
inline int add(R x,R y){static int z;z=x+y;return z<YL?z:z-YL;}
inline int sub(R x,R y){static int z;z=x-y;return z<0?z+YL:z;}
int main(){
R n=in(),s=n-in()+1,m=in();
f[0][0]=1;
for(R i=1;i<=n;++i){
R p=in();
for(R j=m-p;~j;--j)
for(R k=s;k;--k)
f[j+p][k]=add(f[j+p][k],sub(f[j][k-1],f[j][k]));
}
inv[1]=1;LL ans=f[1][s];
for(R i=2;i<=m;++i){
inv[i]=(YL-YL/i)*inv[YL%i]%YL;
ans=(ans+f[i][s]*inv[i])%YL;
}
cout<<ans*m%YL<<endl;
return 0;
}
子集反演
感觉就跟高维差分/IFWT一样?
正好难算,至多好算:\(f(S)=\sum\limits_{T\subseteq S}g(T)\Rightarrow g(S)=\sum\limits_{T\subseteq S}(-1)^{|S|-|T|}f(T)\)
正好难算,至少好算:\(f(S)=\sum\limits_{S\subseteq T}g(T)\Rightarrow g(S)=\sum\limits_{S\subseteq T}(-1)^{|T|-|S|}f(T)\)
还有推广到多重集的子集反演。
设\(\mu(S)=(-1)^{|S|}[S中没有重复元素]\)
(原来莫比乌斯函数就是把整数看作其质因数集合而得来的反演系数啊)
\(f(S)=\sum\limits_{T\subseteq S}g(T)\Rightarrow g(S)=\sum\limits_{T\subseteq S}\mu(S-T)f(T)\)
\(f(S)=\sum\limits_{S\subseteq T}g(T)\Rightarrow g(S)=\sum\limits_{S\subseteq T}\mu(T-S)f(T)\)
子集卷积:已知\(a,b\),求\(c\)使得\(c_S=\sum\limits_{T\subseteq S}a_Tb_{S-T}\)(注意和高维前缀和不一样!)
与高维前缀和的区别主要在于集合大小的限制,只有\(|T|+|S-T|=|S|\)才能产生贡献。
考虑把数组按集合大小分解,\(C_{|S|,S}=\sum\limits_{T\subseteq S}A_{|T|,T}B_{|S-T|,S-T}\)
于是枚举\(i,j\),将\(A_i,B_j\)的或卷积贡献到\(C_{i+j}\)中。最后把\(C\)反演回来就是我们要的\(c\)。
单位根反演
不会
洛谷日报——单位根反演
单位根与其若干应用 by YCB
各种反演细节梳理&模板的更多相关文章
- 图论杂项细节梳理&模板(虚树,圆方树,仙人掌,欧拉路径,还有。。。)
orzYCB 虚树 %自为风月马前卒巨佬% 用于优化一类树形DP问题. 当状态转移只和树中的某些关键点有关的时候,我们把这些点和它们两两之间的LCA弄出来,以点的祖孙关系连成一棵新的树,这就是虚树. ...
- 计算几何细节梳理&模板
点击%XZY巨佬 向量的板子 #include<bits/stdc++.h> #define I inline using namespace std; typedef double DB ...
- 数论细节梳理&模板
初阶 扩展欧拉 \(k\ge\varphi(m)\)时,\(b^k\equiv b^{k\%\varphi(m)+\varphi(m)}(\bmod m\)) 扩展CRT 推式子合并同余方程. htt ...
- 多项式细节梳理&模板(多项式)
基础 很久以前的多项式总结 现在的码风又变了... FFT和NTT的板子 typedef complex<double> C; const double PI=acos(-1); void ...
- C++面向对象类的书写相关细节梳理
类的问题 继承类的原因:为了添加或者替换功能. 1. 继承时重写类的方法 v 替换功能 ① 将所有方法都设置为virtual(虚函数),以防万一. Virtual:经验表明最好将所有方法都设置为vir ...
- 深入浅出ES6(四):模板字符串
作者 Jason Orendorff github主页 https://github.com/jorendorff 反撇号(`)基础知识 ES6引入了一种新型的字符串字面量语法,我们称之为模板字符 ...
- Java 程序动态替换 docx 模板中定制值的实现例子
项目系统中打印功能,导出 word 文档功能是挺常用的,本文介绍自定文档模板,程序实现模板内容中值替代的功能. 模板文件 template.docx 执行 main public static v ...
- 软件工程启程篇章:结对编程和进阶四则运算(197 & 199)
0x01 :序言:无关的事 I wrote a sign called "Dead End" in front of myself, but love crossed it wit ...
- CSP2019-S2参赛总结 暨 近期学习反思
前言 岁月不居,时节如流.眨眼间,2019的联赛就已经落下帷幕了,回忆这一年的学习,有许许多多的事情想写下来.趁联赛结果还未出来,赶紧写下这篇文章,以记录我这段时间的学习和生活. "你怎么又 ...
随机推荐
- 工作时间看股票:采用Excel RTD技术获取和讯网的实时股票行情及深沪港最新指数
本文地址:http://www.cnblogs.com/Charltsing/p/RTD.html QQ:564955427 在Excel里面获取实时数据大概有几种方式:1.定时器+函数2.DDE3. ...
- IOS - UTF-8转码问题
2016.07.06 21:45* 字数 61 阅读 921评论 0喜欢 2 IOS中提供的转码. [utf8str stringByAddingPercentEscapesUsingEncoding ...
- 替换iframe的内容
一般就是点个按钮然后在不跳转页面的情况下显示另外一个页面的内容,显示的速度比较快,ifream还算是常用的吧 用的时候实现方式有以下几种, 1.替换src路径(觉得麻烦,没接触过,就不这样干了) 2. ...
- 快速失败/报错机制 - fail-fast
一.快速报错机制(fail-fast) 这是<Java编程思想>中关于快速报错机制的描述 Java容器有一种保护机制,能够防止多个进程同时修改同一个容器的内容.如果在你迭代遍历容器的过程中 ...
- 异常:fatal: unable to access 'https://git.oschina.net/pcmpcs/library.git/': Could not resolve host
git fork项目时出现的异常. 原因: 我以前用的是ssh地址做的远程通信地址,而这次是用的是https,因为很久没用,所以忘记了以前是用ssh的了.解决方案一:复制ssh协议的地址,然后再关联 ...
- HDU 2003 求绝对值
http://acm.hdu.edu.cn/showproblem.php?pid=2003 Problem Description 求实数的绝对值. Input 输入数据有多组,每组占一行,每行 ...
- Nginx会话保持之nginx-sticky-module模块
Nginx会话保持之nginx-sticky-module模块 - 天行健,君子以自强不息:地势坤,君子以厚德载物. - CSDN博客https://blog.csdn.net/huangjinjin ...
- js文字从左边飞入效果
贴代码之前,我们先讲一下它的原理,我们使用setInterval,让文字一开始置于屏幕看不到的位置,左右上下都可以,然后让它的位置不断移入到屏幕看得到的位置. 下面上代码: html: <h2 ...
- js原生实现div渐入渐出
jq对渐入渐出进行封装,简单的使用连个方法就可以实现.fadeIn(),fadeOut();如果我们界面没有使用jq那么原生怎么实现呢? 我们讲解一下,这个原理.当我们要实现渐入的时候,首先是让隐藏的 ...
- 三、taro路由及设计稿及尺寸单位
一.路由配置 路由配置跟小程序一样,在入口文件的 config 配置中指定好 pages 通过taro API 跳转,详见导航 // 跳转到目的页面,打开新页面 Taro.navigateTo({ u ...