Codeforces Global Round 17 D. Not Quite Lee(gcd)

传送门

题意:

给你一个序列a,对于数 a i a_i ai,将其写成任意 a i a_i ai个连续的数,记第 a i a_i ai组数的和为 s u m i sum_i sumi,现要你找出所有的 s u m i sum_i sumi的组合,使每个组合中的sum的和为0。

思路:

经过推理,不难发现:
对于 a i a_i ai为偶数的情况,它的贡献为 a i / 2 + a i ∗ k a_i/2+a_i*k ai/2+aik,k为任意整数,下同;
对于 a i a_i ai为奇数的情况,它的贡献为 a i ∗ k a_i*k aik
同时,我们也可以得出第一个重要结论:当选取的 a i a_i ai全为奇数时,一定合法。
继续推理可得出下一个结论:**当选取的 a i a_i ai至少有一个奇数时,一定合法。*,证明如下
记我们选取的数的集合为 b 1 , b 2 , b 3 . . . . . . b m b_1,b_2,b_3......b_m b1,b2,b3......bm,且其中存在x个奇数,要证明选取的数合法,
即证明: ( b x + 1 + b x + 2 + . . . . . . + b m ) / 2 (b_{x+1}+b_{x+2}+......+b_{m})/2 (bx+1+bx+2+......+bm)/2= b 1 ∗ k 1 + b 2 ∗ k 2 + . . . . . . b m ∗ k m b_1*k_1+b_2*k_2+......b_m*k_m b1k1+b2k2+......bmkm这个式子成立
而等式右边的式子又可以等价于:gcd( b 1 , b 2 . . . . . . , b m b_1,b_2......,b_m b1,b2......,bm)*k,这一步不多做阐述,
即要证明: ( b x + 1 + b x + 2 + . . . . . . + b m ) / 2 (b_{x+1}+b_{x+2}+......+b_{m})/2 (bx+1+bx+2+......+bm)/2=gcd( b 1 , b 2 . . . . . . , b m b_1,b_2......,b_m b1,b2......,bm)*k,
记S = ( b x + 1 + b x + 2 + . . . . . . + b m ) (b_{x+1}+b_{x+2}+......+b_{m}) (bx+1+bx+2+......+bm)
即证明:gcd( b 1 , b 2 . . . . . . , b m b_1,b_2......,b_m b1,b2......,bm) | S/2
易得:gcd( b 1 , b 2 . . . . . . , b m b_1,b_2......,b_m b1,b2......,bm) | S且由于 b 1 到 b m b_1到b_m b1bm中存在奇数,因而gcd( b 1 , b 2 . . . . . . , b m b_1,b_2......,b_m b1,b2......,bm) 一定不能整除2,所以gcd( b 1 , b 2 . . . . . . , b m b_1,b_2......,b_m b1,b2......,bm) | S/2一定成立,
证毕。
接下来看全为偶数的情况,先说结论:我们将所有的偶数写为 2 k ∗ c 2^k*c 2kc的形式,则选取的序列满足其中k值最小的数为偶数时,就合法。
证明如下
同样是上面的那个式子:gcd( b 1 , b 2 . . . . . . , b m b_1,b_2......,b_m b1,b2......,bm) | S/2,现在b序列全为偶数,将其中每个数都写为 2 k ∗ c 2^k*c 2kc的形式,设最小的k为 k m i n k_{min} kmin,把gcd( b 1 , b 2 . . . . . . , b m b_1,b_2......,b_m b1,b2......,bm)也写为上述形式,则其等于 2 k m i n ∗ x 2^{k_{min}}*x 2kminx,且x一定为奇数,不难得出x | S/2,现在只需要证明: 2 k m i n 2^{k_{min}} 2kmin | S/2,我们将S/2拆成序列的形式来看就是:{ b 1 / 2 + b 2 / 2 + . . . + b m 2 b_1/2+b_2/2+...+b_m2 b1/2+b2/2+...+bm2},在这个除以2之后的序列中,原来刚好包含 2 k m i n 2^{k_{min}} 2kmin的数都变为了包含 2 k m i n − 1 2^{k_{min-1}} 2kmin1的数,而如果这些的个数为奇数,那么再让其除以 2 k m i n 2^{k_{min}} 2kmin则会出现小数,而如果个数为偶数,那么就可以让每两个 2 k m i n − 1 2^{k_{min-1}} 2kmin1合并为一个 2 k m i n 2^{k_{min}} 2kmin,即:选取的序列满足其中k值最小的数为偶数时,就合法。
证毕。
最后的答案就用上面的结论即可得出。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1e9+7;
ll qpow(ll a, ll b)
{
    
    
	ll res = 1;
	while(b)
	{
    
    
		if(b&1)res = res*a%mod;
		b = b>>1;
		a = a*a%mod;
	}
	return res;
}
int sum[40];
ll a[200010];
ll suf[40]; 
int main()
{
    
    
	int n;
	cin>>n;
	ll even = 0,odd = 0;
	for(int i = 1; i <= n; i++)
	{
    
    
		cin>>a[i];
		if(a[i]%2)odd++;
		else even++;
		if(a[i]%2==0)
		{
    
    
			int k = 0;
			ll now = a[i];
			while(now%2==0)
			{
    
    
				now/=2;
				k++;
			}
			sum[k]++;
		}
	}
	for(int i = 31; i >= 1; i--)
	{
    
    
		suf[i] = suf[i+1]+sum[i];
	}
	ll ans = qpow(2,n)+mod-qpow(2,even);
	ans%=mod;
	for(int i = 1; i <= 31; i++)
	{
    
    
		if(sum[i])
		{
    
    
			ans += (qpow(2,sum[i]-1)-1)*qpow(2,suf[i+1]);
			ans%=mod;
		}
	}
	cout<<ans%mod<<endl;
}

猜你喜欢

转载自blog.csdn.net/p15008340649/article/details/121545098