赞
踩
题意: 给两个数 x , y x,y x,y。现在你计算有多少对 a ( a < = x ) a(a<=x) a(a<=x)和 b ( b < = y ) b(b<=y) b(b<=y)使得 ⌊ a b ⌋ = a m o d b \left \lfloor \frac{a}{b} \right \rfloor=a\bmod b ⌊ba⌋=amodb。
思路: 因为
x
x
x和
y
y
y都是
1
e
9
1e9
1e9的范围,可以想到
n
\sqrt{n}
n
求出答案。我们令
⌊
a
b
⌋
=
a
m
o
d
b
=
k
\left \lfloor \frac{a}{b} \right \rfloor=a\bmod b=k
⌊ba⌋=amodb=k,那么
a
a
a可以写成
k
∗
b
+
k
k*b+k
k∗b+k,又因为
k
<
b
k<b
k<b,那么
k
∗
k
<
=
k
∗
b
+
k
=
a
<
=
x
k*k<=k*b+k=a<=x
k∗k<=k∗b+k=a<=x,可得
k
<
=
x
k<=\sqrt{x}
k<=x
,现在考虑知道了
k
k
k能否算出答案呢?考虑如下三个个不等式:
{
1
<
=
b
<
=
y
1
<
=
k
∗
b
+
k
<
=
x
k
<
b
解得:
k
<
b
<
=
m
i
n
(
y
,
x
/
k
−
1
)
k<b<=min(y,x/k-1)
k<b<=min(y,x/k−1)
我们枚举
k
k
k就可以得到答案啦。
//#pragma GCC optimize(2) #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<map> #include<cmath> #include<cctype> #include<vector> #include<set> #include<queue> #include<algorithm> #include<sstream> #include<ctime> #include<cstdlib> #define X first #define Y second #define L (u<<1) #define R (u<<1|1) #define pb push_back #define mk make_pair #define Mid (tr[u].l+tr[u].r>>1) #define Len(u) (tr[u].r-tr[u].l+1) #define random(a,b) ((a)+rand()%((b)-(a)+1)) #define db puts("---") using namespace std; //void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); } //void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); } //void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); } typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f; const double eps=1e-6; int x,y; int main() { // ios::sync_with_stdio(false); // cin.tie(0); int _; scanf("%d",&_); while(_--) { LL ans=0; scanf("%d%d",&x,&y); for(LL k=1;k*k<x;k++) ans+=max(0ll,min(1ll*x/k-1,1ll*y)-k); printf("%lld\n",ans); } return 0; } /* */
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。