You Are Given Some Letters...(CodeForces-1202F)(数论分块,思维题)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_37555704/article/details/102668111

文章目录

题目

CF
在这里插入图片描述
注意最后一个周期可以不是满的,其实说最小有点不严谨
1 a , b 1 0 9 1\le a,b\le 10^9

思路

首先我们思考一个比较暴力的做法,枚举周期 k k ,我们记 a + b = n a+b=n
我们假设一个周期内 A A 的数量为 x x B B 的数量为 y y ,我们可以得到:
{ 0 a n k x x 0 b n k y y \begin{cases} 0\le a-\lfloor \frac{n}{k}\rfloor*x\le x\\ 0\le b-\lfloor \frac{n}{k}\rfloor*y\le y \end{cases}
我们可以得到
{ a n k + 1 x a n k b n k + 1 y b n k \begin{cases} \frac{a}{\lfloor \frac{n}{k}\rfloor+1}\le x\le \frac{a}{\lfloor \frac{n}{k}\rfloor}\\ \frac{b}{\lfloor \frac{n}{k}\rfloor+1}\le y\le \frac{b}{\lfloor \frac{n}{k}\rfloor} \end{cases}
因为 x , y x,y 均为整数,我们又可以写为:
{ a n k + 1 x a n k b n k + 1 y b n k \begin{cases} \lceil\frac{a}{\lfloor \frac{n}{k}\rfloor+1}\rceil\le x\le \lfloor\frac{a}{\lfloor \frac{n}{k}\rfloor}\rfloor\\ \lceil\frac{b}{\lfloor \frac{n}{k}\rfloor+1}\rceil\le y\le \lfloor\frac{b}{\lfloor \frac{n}{k}\rfloor}\rfloor \end{cases}
看到这个我们就想到了数论分块,因为 n k \lfloor \frac{n}{k}\rfloor 最多只有 2 n 2\sqrt n 个取值,枚举 t = n k t=\lfloor \frac{n}{k}\rfloor 得到 k k 的取值 [ l , r ] [l,r]
我们可以得到:
{ a t + 1 x a t b t + 1 y b t \begin{cases} \lceil\frac{a}{t+1}\rceil\le x\le \lfloor\frac{a}{t}\rfloor\\ \lceil\frac{b}{t+1}\rceil\le y\le \lfloor\frac{b}{t}\rfloor \end{cases}
{ x [ a t + 1 , a t ] y [ b t + 1 , b t ] \begin{cases} x\in[\lceil\frac{a}{t+1}\rceil, \lfloor\frac{a}{t}\rfloor]\\ y\in[\lceil\frac{b}{t+1}\rceil, \lfloor\frac{b}{t}\rfloor] \end{cases}
此时 x + y = k x+y=k k [ l , r ] k\in[l,r]
于是 k [ a t + 1 + b t + 1 , a t + b t ] k\in[\lceil\frac{a}{t+1}\rceil+\lceil\frac{b}{t+1}\rceil,\lfloor\frac{a}{t}\rfloor+\lfloor\frac{b}{t}\rfloor]
于是满足区间合法的情况下求交即是对答案的贡献
注意数论分块写法

代码

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<climits>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
int read(){
    int f=1,x=0;char c=getchar();
    while(c<'0'||'9'<c){if(c=='-')f=-1;c=getchar();}
    while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return f*x;
}
#define MAXN 1000000000
#define INF 0x3f3f3f3f
int main(){
	int a=read(),b=read(),n=a+b,ans=0;
	for(int l=1,r;l<=n;l=r+1){
		r=n/(n/l);
		int t=n/l,al=(a+t)/(1+t),ar=a/t,bl=(b+t)/(1+t),br=b/t;
		if(al<=ar&&bl<=br) ans+=max(0,min(r,ar+br)-max(l,al+bl)+1);
	}
	printf("%d\n",ans);
    return 0;
}

后记

猜你喜欢

转载自blog.csdn.net/qq_37555704/article/details/102668111
今日推荐