CF1202F You Are Given Some Letters... 题解

Codeforces
Luogu

P.S.

有意思的好题。

Description.

好的字符串定义为其满足有 \(a\)a\(b\)b
求所有好的字符串有多少种可能的不同循环节。

\[a,b\le 10^9 \]

Solution.

下文设 \(k\) 为循环节数量,\(a_1\)\(b_1\) 分别表示一个循环节内有多少 ab

\[k\times a_1\le a\le (k+1)\times a_1 \]

\[k\times b_1\le b\le (k+1)\times b_1 \]

\[\therefore \left\lfloor\frac {a+k}{k+1}\right\rfloor\le a_1\le\left\lfloor\frac ak\right\rfloor \]

\[\therefore \left\lfloor\frac {b+k}{k+1}\right\rfloor\le b_1\le\left\lfloor\frac bk\right\rfloor \]

同时也有

\[\left\lfloor\frac{a+b+k}{k+1}\right\rfloor\le a_1+b_1\le\left\lfloor\frac{a+b}k\right\rfloor \]

\[len=a_1+b_1 \]

所以只需要整除分块就可以了

Coding.

//我是一发子弹,子弹没有感情,因此,没有迷茫,只会飞向目标。{{{
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
	x=0;char c=getchar(),f=0;
	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	f?x=-x:x;
}/*}}}*/
int a,b,n;ll rs=0;
int main()
{
	read(a),read(b),n=a+b;
	for(int l=1,r,k;l<=n;l=r+1)
	{
		k=n/l,r=n/k;if(a<k||b<k) continue;
		int la=(a+k)/(k+1),ra=a/k,lb=(b+k)/(k+1),rb=b/k;
		if(la<=ra&&lb<=rb) rs+=max(0,min(r,rb+ra)-max(l,la+lb)+1);
	}
	return printf("%lld\n",rs),0;
}
原文地址:https://www.cnblogs.com/pealfrog/p/14989707.html