TrickGCD HDU
来源:互联网 发布:js控制标签显示隐藏 编辑:程序博客网 时间:2024/05/20 02:56
You are given an array AA , and Zhu wants to know there are how many different array BB satisfy the following conditions?
- 1≤Bi≤Ai
- For each pair( l , r ) (1≤l≤r≤n) , gcd(bl,bl+1…br)≥2
Input
The first line is an integer T(1≤T≤10) describe the number of test cases.
Each test case begins with an integer number n describe the size of array AA.
Then a line contains nn numbers describe each element of AA
You can assume that 1≤n,Ai≤1051≤n,Ai≤105
Output
For the kth test case , first output “Case #k: ” , then output an integer as answer in a single line . because the answer may be large , so you are only need to output answer mod 109+7
Sample Input
1
4
4 4 4 4
Sample Output
Case #1: 17
这题之前做过,遇到一道类似的题,想来写个题解
这题有两种思想的解法,但是殊途同归,一个是容斥思想,另一个是莫比乌斯反演,先谈谈容斥,gcd要大于2,所以我们把bi里最小的数分解质因子,然后用状压枚举质因子组合,以前做过类似是求gcd要等于1的对数,做法是我们把所有gcd大于1的对数找出,然后总数减去。
看看莫比乌斯反演,我们能不能这样,把所有gcd等于1的对数找出,然后总数减去,设
则:
设
反演得:
所以
易知:
所以:
我们知道
所以
其实我用容斥做得到式子和这是一模一样的,其实容斥和莫比乌斯函数实质上是一样的(当然你可以用其他的方式实现容斥)
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<bitset>#include<vector>#define N 200005#define mod 1000000007using namespace std;typedef long long ll;int mu[N];vector<int> prime;bool pri[N];void getM(){ memset(pri,true,sizeof(pri)); mu[1]=1; for(int i=2;i<N;i++) { if(pri[i]) { prime.push_back(i); mu[i]=-1; } for(int j=0;j<prime.size()&&prime[j]*i<N;j++) { pri[prime[j]*i]=false; if(i%prime[j]) mu[prime[j]*i]=-mu[i]; else { mu[prime[j]*i]=0; break; } } }}int num[N];ll P(ll a,ll b){ ll ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans;}int main(){ getM(); int t; int n; scanf("%d",&t); int x; int cal=1; while(t--) { scanf("%d",&n); int minn=10000000; int maxx=-1; memset(num,0,sizeof(num)); for(int i=0;i<n;i++) { scanf("%d",&x); minn=min(minn,x); maxx=max(maxx,x); num[x]++; } for(int i=100000;i>0;i--) num[i-1]+=num[i]; long long ans=0; //cout<<"min "<<minn<<endl; for(int i=2;i<=minn;i++) { if(!mu[i]) continue; ll temp=1; ll now=1; int p=i; while(p<=maxx) { temp=temp*P(now++,num[p]-num[p+i])%mod; p+=i; } ans=(-mu[i]*temp+ans+mod+mod)%mod; } printf("Case #%d: %lld\n",cal++,ans); } return 0;}
- TrickGCD HDU
- TrickGCD HDU
- HDU 6053 TrickGCD
- HDU 6053 TrickGCD
- HDU-6053 TrickGCD
- hdu 多校 TrickGCD
- hdu 6053 TrickGCD
- HDU 6053 TrickGCD
- [HDU]6053 TrickGCD
- HDU 6053 TrickGCD 数论
- hdu--6053--TrickGCD
- hdu-6053TrickGCD
- HDU 6053 TrickGCD
- HDU 6503 TrickGCD
- HDU 6053 TrickGCD
- HDU 6053 TrickGCD DP(筛法)
- hdu 多校联赛 TrickGCD
- HDU 6053 TrickGCD(枚举)
- resultMap与resultType、parameterMap与 parameterType的区别
- ubuntu如何使用root权限
- Struts2深入详解--- 认识Struts2
- Switchhosts软件的使用
- 解决从mysql表中多列导出数据到csv合并成一列的问题
- TrickGCD HDU
- 【论文阅读】Illuminating Pedestrians via Simultaneous Detection & Segmentation
- 电商高复用购物车业务分析和代码实现
- Binary Search:162. Find Peak Element
- 【nginx】nginx与apache详细性能对比
- 获取从服务器传来的key-value对
- ajax+post+json+@requestBody走天下
- javascript各种设计模式
- 第二次自考总结