hdu 6053 莫比乌斯函数(容斥)
来源:互联网 发布:数据研究中心美国大学 编辑:程序博客网 时间:2024/06/11 01:06
题意:两个序列,A,B,A序列给出,Bi<=Ai,问满足所有区间的gcd l r != 1 的B序列的方案数
思路:枚举B整体的GCD,直接枚举显然会重复计算,顾使用莫比乌斯进行容斥,单组因子的方案数就是sum (ai/p)
显然直接枚举时间复杂度为n*m m=min ai ,在这里我们做一个桶的处理,并求后缀和,就直接计算出 ai/p =ni 的个数
知道所以的ni就可以算出sum (ai/p) ,这里处理的方法类似筛法,时间复杂度约为nlogn,加上公式中的快速幂,时间复杂度nlognlogn
代码:
#include<bits/stdc++.h>using namespace std;#define X first#define Y second#define PB push_back#define MP make_pair#define MEM(a,b) memset(a,b,sizeof(a))typedef long long ll;typedef pair<int,int> pii;const ll mod = 1e9+7;const int maxn =2e5+10;ll n,k,mi,ans,mx;ll a[maxn],T[maxn];const int MAXN = 250000;bool check[MAXN+10];int prime[MAXN+10];int mu[MAXN+10];void Moblus(){ memset(check,false,sizeof(check)); mu[1] = 1; int tot = 0; for(int i = 2; i <= MAXN; i++){ if( !check[i] ){ prime[tot++] = i; mu[i] = -1; } for(int j = 0; j < tot; j++){ if(i * prime[j] > MAXN) break; check[i * prime[j]] = true; if( i % prime[j] == 0){ mu[i * prime[j]] = 0; break; } else{ mu[i * prime[j]] = -mu[i]; } } }}ll qpow(ll a,ll b){ ll ret=1; while(b){ if(b&1) ret=(ret*a)%mod; a=(a*a)%mod; b>>=1; } return ret;}int main(){ int t,ca=1; Moblus(); scanf("%d",&t); while(t--){ MEM(T,0); scanf("%d",&n); mi=1e9;ans=0;mx=-1e9; for(int i=0;i<n;i++) scanf("%d",&a[i]),mi=min(mi,a[i]),mx=max(mx,a[i]),T[a[i]]+=1; for(int i=maxn-5;i>0;i--) T[i]+=T[i+1]; for(ll i=2;i<=mi;i++){ ll ret=-mu[i]; ll p=i,cnt=1; while(p<=mx) ret=(ret*qpow(cnt++,T[p]-T[p+i]))%mod,p=p+i; ans= (ret+ans+mod+mod)%mod; } printf("Case #%d: %lld\n",ca++,(ans+mod)%mod); } return 0;}
再附上一种容斥写法
#include<bits/stdc++.h>using namespace std;#define X first#define Y second#define PB push_back#define MP make_pair#define MEM(a,b) memset(a,b,sizeof(a))typedef long long ll;typedef pair<int,int> pii;const ll mod = 1e9+7;const int maxn =1e6+10;ll n,k;ll mi,ans,mx;ll a[maxn],T[maxn];vector<int> P;const int MAXN=10000;int prime[MAXN+10];void getPrime(){ memset(prime,0,sizeof(prime)); for(int i=2; i<=MAXN; i++){ if(!prime[i])prime[++prime[0]]=i; for(int j=1; j<=prime[0]&&prime[j]<=MAXN/i; j++){ prime[prime[j]*i]=1; if(i%prime[j]==0) break; } }}ll qpow(ll a,ll b){ ll ret=1; while(b){ if(b&1) ret=(ret*a)%mod; a=(a*a)%mod; b>>=1; } return ret;}void dfs(ll x,int p,int id){ if(x>mi) return; if(id!=0){ ll ret=1; ll pp=x,cnt=1; while(pp<=mx) ret=(ret*qpow(cnt++,T[pp]-T[pp+x]))%mod,pp=pp+x; if(p)ans=(ans+ret)%mod; else ans=(ans-ret+mod)%mod; } for(int i=id+1;i<=prime[0];i++) dfs(x*prime[i],p^1,i);}int main(){ int t,ca=1; scanf("%d",&t); getPrime(); while(t--){ scanf("%d",&n); MEM(T,0);mi=1e9;ans=0;mx=-1e9; for(int i=0;i<n;i++) scanf("%d",&a[i]),mi=min(mi,a[i]),mx=max(mx,a[i]),T[a[i]]+=1; for(int i=maxn-5;i>0;i--) T[i]+=T[i+1]; dfs(1,0,0); printf("Case #%d: %lld\n",ca++,(ans+mod)%mod); } return 0;}
阅读全文
3 0
- hdu 6053 莫比乌斯函数(容斥)
- hdu 6053 TrickGCD(容斥,分段,莫比乌斯函数)
- hdu 6053 (莫比乌斯反演+容斥)
- HDU 6053 TrickGCD 【容斥定理】【莫比乌斯函数】
- 【 hdu 6053】 TrickGCD 【数论 容斥 + 莫比乌斯函数 】
- hdu 6053 TrickGCD 容斥 莫比乌斯
- hdu 6053 TrickGCD 【容斥&筛法|莫比乌斯】
- hdu 6053 TrickGCD 容斥原理(莫比乌斯工具)
- hdu 1695 GCD 欧拉函数+容斥 ||莫比乌斯反演
- Hdu 5514 类莫比乌斯函数 容斥原理
- HDU 1695 数论 容斥 欧拉函数 || 莫比乌斯反演
- hdu 5212 code 容斥~或者莫比乌斯
- HDU 1695 GCD 莫比乌斯,容斥原理
- codeforces803F Coprime Subsequences -- 莫比乌斯函数+容斥
- HDU6053(莫比乌斯函数+容斥定理)
- hdu6053 TrickGCD 莫比乌斯函数 容斥原理
- hdu6053-容斥+莫比乌斯函数+优化
- TrickGCD(莫比乌斯函数,容斥)
- TensorFlow实现自编码器
- Java多线程系列----Fork/Join框架介绍
- error C2360: initialization of 'j' is skipped by 'case' label
- HDU6047(数学题)
- 85 Maximal Rectangle (最大矩形)
- hdu 6053 莫比乌斯函数(容斥)
- hpuoj 【1287】数组最值 【水题】
- 爬去杭电hdu做题情况
- C# WPF 实现鼠标固定在指定范围内运动
- jQuery EasyUI中的Layout布局(二)
- CS231n课程笔记翻译8:神经网络笔记 part3
- [leetcode] 231. Power of Two
- 剑指offer题65
- fastText原理及应用