\[ \begin{aligned} \sum_{d=1}^n(-1)^{\lfloor d\sqrt r\rfloor}=&\sum_{d=1}^n(-1)^{\lfloor d\sqrt r\rfloor\ mod\ 2}\\ =&\sum_{d=1}^n1-2(\lfloor d\sqrt r\rfloor\ mod\ 2)\\ =&n-\sum_{d=1}^n2(\lfloor d\sqrt r\rfloor-2\lfloor\frac{\lfloor d\sqrt r\rfloor}{2}\rfloor)\\ =&n+4\sum_{d=1}^n\lfloor\frac{d\sqrt r}{2}\rfloor-2\sum_{d=1}^n\lfloor d\sqrt r\rfloor \end{aligned} \]
将问题一般化,记\(x=\sqrt r\),其实我们求的是
\[ \sum_{i=1}^n \lfloor \frac{ax+b}{c} i \rfloor \]
我们再记\(\frac{ax+b}{c}=k\),最后就是求
\[ \sum_{i=1}^n \lfloor ki \rfloor \]
仿照类欧的思想分类讨论
(1)若\(k\geq 1\)
\[ \begin{aligned} \sum_{i=1}^n \lfloor ki\rfloor=&\sum_{i=1}^n\lfloor ki-\lfloor k\rfloor i+\lfloor k\rfloor i \rfloor\\ =&\sum_{i=1}^n\lfloor ki-\lfloor k\rfloor i\rfloor+\frac{n(n+1)}{2}\lfloor k\rfloor\\ =&\sum_{i=1}^n \lfloor \frac{ax+b-c\lfloor \frac{ax+b}{c} \rfloor*i}{c}\rfloor+\lfloor k\rfloor * \frac{n(n+1)}{2} \end{aligned} \]
(2)若\(k<1\),继续考虑其几何意义
\[ \begin{aligned} \sum_{i=1}^n \lfloor ki\rfloor=&\sum_{i=1}^n\sum_{j=1}^{\lfloor k*n\rfloor} [k*i>j]\\ =&\sum_{i=1}^n\sum_{j=1}^{\lfloor k*n\rfloor} [i>\frac{j}{k}]\\ =&\sum_{j=1}^{\lfloor k*n\rfloor}\sum_{i=1}^n [i>\frac{j}{k}]\\ =&\sum_{j=1}^{\lfloor k*n\rfloor} (n-\lfloor \frac{j}{k}\rfloor)\\ =&\lfloor k*n\rfloor*n-\sum_{j=1}^{\lfloor k*n\rfloor}\lfloor \frac{j}{k}\rfloor \end{aligned} \]
注意到使用(2)的时候需要k是一个无理数,所以预处理\(r\)是奇数时需要特判,同时递归时需要分母有理化
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
ll n,r;
double x;
int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
}
ll gcd(ll x,ll y)
{
if ((!x) || (!y)) return x+y;
else return gcd(y,x%y);
}
ll solve(ll a,ll b,ll c,ll n)
{
if (!n) return 0;
if (n==1) return (a*x+b)/c;
ll g=gcd(gcd(a,b),c);
a/=g;b/=g;c/=g;
ll k=(a*x+b)/c;
if (k!=0)
{
return k*n*(n+1)/2+solve(a,b-c*k,c,n);
}
else
{
ll tmp=(a*x+b)/c*n;
return tmp*n-solve(a*c,-b*c,a*a*r-b*b,tmp);
}
}
int main()
{
int T=read();
while (T--)
{
n=read();r=read();
x=sqrt((double)r);ll tmp=(ll)x;
if (tmp*tmp==r)
{
if (tmp&1) printf("%lld\n",n-2*((n+1)>>1));
else printf("%lld\n",n);
}
else printf("%lld\n",n-solve(1,0,1,n)*2+solve(1,0,2,n)*4);
}
return 0;
}