HDU 6053 莫比乌斯反演
来源:互联网 发布:jqueryrotate.js教程 编辑:程序博客网 时间:2024/05/21 22:43
题目
TrickGCD
题意
给一个数组 {Ai},求能得到多少种数列 {Bi}
{Bi} 需要满足:
1. 1 ≤ Bi ≤ Ai
2. 对于(l,r)( 1 ≤ l ≤ r ≤ n ),gcd(bl, bl+1 … br) >= 2
题解
这道题需要用到莫比乌斯反演的知识,如果不会可以先看一下
http://blog.csdn.net/acdreamers/article/details/8542292 这篇博文。
第二个条件其实就是 gcd(b1, b2 … bn) >= 2 ,然后可以根据下面这些公式得到最终解:
gcd(b1, (b2 … bn) >= 2) = (gcd ≥ 1) - (gcd = 1)
(gcd ≥ 1) = a1 * a2 * … * an
(gcd = 1) =
但是这样的时间复杂度是 n2 ,还要用分块的方法优化一下,用 sum[i] 表示 Aj <= i 的总数,对于每个 x ,当 d 在 [i,i+d-1] 这样一区间内,x/d 的值是一样的。所以就可以用快速幂将这段累乘优化为 pow(x/d, (sum[i+d-1] - sum[i-1])) ,这样时间复杂度就变为 nlogn 。
代码
#include <algorithm>#include <bitset>#include <cstring>#include <cstdio>#include <cmath>#include <cstdlib>#include <climits>#include <iostream>#include <list>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>using namespace std;const int N = 100005;int a[N],sum[N << 1];bool check[N];int prime[N];int mu[N];void Moblus() { memset(check,false,sizeof(check)); mu[1] = 1; int tot = 0; for(int i = 2; i <= N; i++) { if( !check[i] ) { prime[tot++] = i; mu[i] = -1; } for(int j = 0; j < tot; j++) { if(i * prime[j] > N) break; check[i * prime[j]] = true; if( i % prime[j] == 0){ mu[i * prime[j]] = 0; break; } else { mu[i * prime[j]] = -mu[i]; } } }}const long long mod = 1000000007;long long pow_mod(long long a,long long b){ long long ans = 1,base = a; while(b){ if(b % 2) ans = ans * base % mod; base = base * base % mod; b >>= 1; } return ans;}int main(){ int t; cin >> t; Moblus(); for(int cnt = 1;cnt <= t; ++cnt){ int n; cin >> n; memset(sum,0,sizeof(sum)); int mn = INT_MAX; int mx = 0; for(int i=1;i<=n;++i){ scanf("%d",a + i); mn = min(a[i],mn); mx = max(a[i],mx); ++sum[a[i]]; } for(int i=2;i<=mx + mn;++i){ sum[i] += sum[i-1]; } long long ans = 0; for(int i=2;i<=mn;++i){ long long temp = 1; if(mu[i] != 0){ for(int j=i;j<=mx;j+=i){ temp = (temp * pow_mod(j/i,sum[j+i-1] - sum[j-1])) % mod; } ans = (ans - mu[i] * temp + mod) % mod; } } cout<<"Case #"<< cnt <<": "<<ans<<endl; } return 0;}
阅读全文
0 0
- HDU 6053 莫比乌斯反演
- hdu 6053-莫比乌斯反演
- HDU 6053 莫比乌斯反演
- hdu 1695 莫比乌斯反演
- hdu 5072 莫比乌斯反演
- hdu 1695 莫比乌斯反演
- hdu 1695 莫比乌斯反演
- HDU 5656 (莫比乌斯反演)
- HDU 4675 (莫比乌斯反演)
- hdu 5212(莫比乌斯反演)
- hdu 1695 莫比乌斯反演
- HDU 1695 莫比乌斯反演
- HDU 6134 莫比乌斯反演
- HDU 6134 莫比乌斯反演
- hdu 6134(莫比乌斯反演)
- hdu 1695 莫比乌斯反演
- HDU 6053 TrickGCD(莫比乌斯反演+分块)
- HDU 6053 TrickGCD 莫比乌斯反演||筛法
- 鱼眼镜头的标定及矫正
- Hdu 6157 The Karting 多维DP
- 80X86汇编子程序的设计与调用
- 初探指针
- 头条
- HDU 6053 莫比乌斯反演
- 多维数组按照指定项排序
- jetson tk1开发(2)-安装cuda和cudnn
- swift------导入OC三方类找不到头文件的解决方法
- CentOS安装rz sz命令
- 矩阵快速幂模板
- 集合
- Java中的异常和处理详解
- fjlfjlfjl