思路
对于偶数,可以采用裴蜀定理确定为是中间的奇数的数量,并且数量是占一半的。所以只需要先确定最小的gcd,然后大的任选,就可以求出这个gcd中不满足条件的数量的个数。
采用固定gcd,从而求解就可以了。
又是和二进制有关,并且配上了申请的裴蜀定理。
代码
/*
数论菜鸡
连续的整数进行组成
所有的序列和都是0,长度是bi
只要有奇数,随便怎么样都是可以的
考虑全部是偶数的序列就可以了
长度相同可以,长度不同也是可能可以的
每一次移动,变化的数值是移动的,sum(bi)=bi/2 + kbi k为任意整数
则(a1+a2+a3......)/2 = ka1 + ka2 + ka3 ......
也就是只需要(a1+a2+a3)除去gcd后,奇数的个数为偶数就可以了
这里采用减去的方法
选奇数的个数的方案数量有一半的数量
比他大的任意取就可以了
求和+裴蜀定理
化简数组中gcd的数量
数学还是不是特别擅长呀
*/
#include <bits/stdc++.h>
using namespace std;
const int M = 1e6 + 5;
#define endl '\n'
#define int long long
using pii = pair<int, int>;
const int mod=1e9+7;
int kpow(int a,int b) {
int ans=1;
while(b) {
if(b&1)ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
int num[50];
void solve() {
int n;cin>>n;
for(int i=1,x;i<=n;i++) {
cin>>x;
int cnt=0;
while(x%2==0)x/=2,cnt++;
num[cnt]++;
}//统计数的数量
int sum=0;
for(int i=1;i<=32;i++)
if(num[i]) {//保证gcd为这个数
int tmp=kpow(2,num[i]-1);
for(int j=i+1;j<=32;j++)
tmp=tmp*kpow(2,num[j])%mod;//比他大的都是不增加贡献的
sum=(sum+tmp)%mod;
}
cout<<(kpow(2,n)-1-sum+mod)%mod<<endl;
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
solve();
return 0;
}
标签:gcd,奇数,int,Quite,ans,mod,数量,Lee
From: https://www.cnblogs.com/basicecho/p/17263829.html