CF271E - Three Horses

发布时间 2023-06-21 00:16:17作者: jucason_xu

首先,如果 \((x,x+d)\) 可以实现,那么任意的 \((y,y+d)\) 都可以被实现。

也就是,差相等的所有数对等价。

如果 \(y\ge x\),显然可以仅通过 \((x+1,y+1)\) 达成目的。所以问题等价于证明 \((x,x+d)\)\((1,d+1)\) 等价。

我们找到一个 \(N\) 使得 \(2^N\ge x\),然后如果我们能得到 \((2^N,d2^N+2^N)\),也就能得到 \((1,d+1)\)

然后我们可以得到 \((2^N,2^N+d)\)。然后通过一系列操作得到 \((2^N+d,2^N+2d),(2^N+2d,2^N+3d)\cdots (2^N+(2^{N}-1)d,2^N+2^Nd)\)。每次相邻两项合并一下之后就可以得到 \((2^N,d2^N+2^N)\) 了。

所以我们证明了差 \(k=y-x\) 相等的数对等价。那么我们就看看三种操作的影响。

\((x+1,y+1)\)\(k\) 不变

\((x/2,y/2)\)\(k/2\)

\((a,b)(b,c)\)\(k\) 相加。

也就是,我们相当于从 \(x\) 开始在生成一个数集,每次可以选两个相加或者 \(/2\)

我们发现,假如我们一开始选定的数是 \(d=2^yx\)\(x\) 是奇数),那么等价于 \(d=x\)。而这个因子 \(x\) 会一直保留(因为只有素因子)。所以其生成的所有答案都会带有因子 \(x\)

那么,我们先对所有的 \(a_i\) 去掉所有 \(2\),然后求 \(\gcd\)\(g\)。我们需要的 \(d\) 不能含有 \(g\) 的素因子以外的素因子。而不含某个素因子是简单的,我们可以把做 \(x\) 次相加看作 \(\*x\),就解决了。

那么,就枚举 \(g\) 的所有因子,然后枚举所有 \(d=2^yg\),每个差为 \(d\) 的数对在 \([1,m]\) 中一共有 \(m-d\) 个。复杂度 \(\sqrt{a}\log a\)


ll n,a,g=0,m,ans;
inline void solve(ll x){
	rep(i,0,30)if((x<<i)<=m){
		ans+=(m-(x<<i));
	}
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m;
	rp(i,n){
		cin>>a;a--;
		while(!(a&1))a>>=1;
		g=__gcd(a,g);
	}
	for(ll i=1;i*i<=g;i++)if(g%i==0){
		solve(i);
		if(i*i!=g)solve(g/i);
	}cout<<ans<<endl;
	return 0;
}
//Nyn-siyn-hert