BZOJ3817 Sum(类欧几里得算法)

设$t=\sqrt r$,原题转化为$\sum_{x=1}^n(4*\lfloor\frac{tx}2\rfloor-2*\lfloor tx\rfloor)$
考虑如何求$\sum_{x=1}^n\lfloor\frac{bt+c}ax\rfloor$
开始我写了一个真欧几里得来求直线下整点数目,然后由于里头含小数所以不对。
于是学习了一下新姿势,思想其实差不多。
先把a,b,c同时除以gcd(a,b,c),防止爆int。
之后把斜率变成$\frac{bt+c}a-\lfloor\frac{bt+c}a\rfloor$,并计算对应贡献。
第三步把x,y轴互换,这时斜率变成了倒数,即$\frac a{bt+c}=\frac {abt-ac}{b^2t^2-c^2}$
特判r是完全平方数的时刻,因为这样直线上会有点,所以减的时候会减多。
补充:真欧几里得算法:
$$\sum_{0<=x<n} \lfloor \frac{ax+b}{c} \rfloor=n*\lfloor \frac{b}{c} \rfloor+\frac{n*(n-1)}{2}*\lfloor \frac{a}{c} \rfloor+\sum_{0<=x<\lfloor \frac{(a\%c)*n+b\%c}{c} \rfloor} \lfloor \frac{cx+(an+b)\%c}{a\%c} \rfloor$$

#include <cstdio>
#include <cmath>

int T,n,r;
double t;
int gcd(int a,int b) {return b?gcd(b,a%b):a;}
int sol(int n,int a,int b,int c) {
    if (!n) return 0;
    int tmp=gcd(gcd(a,b),c); a/=tmp; b/=tmp; c/=tmp;
    tmp=(t*b+c)/a; int sum=1ll*n*(n+1)*tmp>>1;
    c-=tmp*a; tmp=(t*b+c)*n/a;
    return sum+n*tmp-sol(tmp,b*b*r-c*c,a*b,-a*c);
}

int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&r),t=sqrt(r);
        if((int)t==t) printf("%d\n",(r&1)?((n&1)?-1:0):n);
        else printf("%d\n",n+4*sol(n,2,1,0)-2*sol(n,1,1,0));
    }
    return 0;
}
时间: 2024-08-12 03:57:13

BZOJ3817 Sum(类欧几里得算法)的相关文章

bzoj3817 Sum 类欧几里得算法

这道题目solution写了两种做法,都讲一下吧. 首先,令x=r^0.5,显然,如果x>2,则可以不断减2到小于二:如果x>1,那么变为2-x.因此此时必有x<1.(特判r为完全平方数的情况).那么令y=1/x,则: 题目等价于在数轴从0~n,以y长度为一个区间(左闭右开)黑白交替染色,求黑色部分覆盖的整点减去白色部分覆盖的整点.然后把最后面零散的部分暴力计算,如果最后一个是黑色的也暴力计算.那么这个时候黑白段数相等,且每一段黑(白)都至少覆盖[y]个点恰好各自抵消[y],那么将每一段

[P5170] 类欧几里得算法

のすたの"类欧几里得算法"第二题 P5170 [题意]已知\(n,a,b,c\),求 \[ \begin{aligned} f_{1}(a,b,c,n)&=\sum_{i=0}^n\lfloor\dfrac{ai+b}{c}\rfloor\f_{2}(a,b,c,n)&=\sum_{i=0}^n\lfloor\dfrac{ai+b}{c}\rfloor^2\f_{3}(a,b,c,n)&=\sum_{i=0}^n\lfloor\dfrac{ai+b}{c}\rf

类欧几里得算法浅谈(部分)

学习类欧几里得算法,因为是蒟蒻,感觉网上很多都看不懂,所以自己写一篇快活快活 第一类求和式: \(F(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{a*i+b}{c}\rfloor\) 对于这样形式的求和,我们有以下的推导: 1.当\(a>=c\)并且\(b>=c\)时,我们有: 对于\(\lfloor\frac{a}{c}\rfloor\), 它实际等价于\(\lfloor\frac{a\mod c}{c}\rfloor+\lfloor\frac{a}{c}\rfloo

类欧几里得算法

对于求和式 $f(a,b,c,n)=\sum_{i=0}^n \lfloor \frac{ai+b}{c} \rfloor$ 当 $a \geq c$ 或 $b \geq c$ 时,设 $a'=a \; mod \; c$,$b'=b \; mod \; c$,有 $$\begin{align*} f(a,b,c,n) = & \sum_{i=0}^n \; \lfloor \frac{ai+b}{c} \rfloor \\ = & \sum_{i=0}^n \; \lfloor \fra

数论,类欧几里得算法

类欧几里得部分转载自不来也不去的一只失忆蝴蝶.%%%

模板 - 类欧几里得算法

用来快速求解 $\sum\limits_{i=0}^{n}\lfloor \frac{ai+b}{c} \rfloor,\sum\limits_{i=0}^{n}{\lfloor \frac{ai+b}{c} \rfloor}^2,\sum\limits_{i=0}^{n}i\lfloor \frac{ai+b}{c} \rfloor $ 有多快呢?据说是log的?反正abc取1e9可以200ms过1e5组询问-- #include <bits/stdc++.h> typedef long l

[补档计划] 类欧几里得算法

$$\begin{aligned} f(a, b, c, n) & = \sum_{i = 0}^n \lfloor \frac{ai + b}{c} \rfloor \\ & = \sum_{i = 0}^n \sum_{j = 0}^{m-1} [j < \lfloor \frac{ai + b}{c} \rfloor] \\ & = \sum_{i = 0}^n \sum_{j = 0}^{m-1} [j + 1 \le \lfloor \frac{ai + b}{c}

【LuoguP4433】[COCI2009-2010#1] ALADIN(含类欧几里得算法推导)

题目链接 题意简述 区间赋值模意义下等差数列,询问区间和 \(N\leq 10^9,Q\leq 10^5\) Sol 每次操作就是把操作区间\([L,R]\)中的数赋值成: \[(X-L+1)*A\ mod\ B\] 考虑用线段树维护. 我们只需要能快速知道一段区间\([l,r]\)被覆盖后的和就行了,因为覆盖的标记易于下传: \[\sum_{i=l}^{r} (i-L+1)*A\ mod\ B\] 根据基础的数学知识,mod显然不好算,把它拆开: \[\sum_{i=l}^r (i-L+1)*

[BZOJ3817]Sum

试题描述 给定正整数N,R.求 输入 第一行一个数 T,表示有 T 组测试数据. 接下来 T 行,每行两个正整数 n,r. 输出 输出 T 行,每行一个整数表示答案. 输入示例 3 3 5 3 6 3 7 输出示例 3 1 -1 数据规模及约定 对于 100% 的数据,满足 n≤10^9,r≤10^4,T≤10^4. 题解 新技能:类欧几里得算法. #include <iostream> #include <cstdio> #include <cstdlib> #inc