小白月赛三 D妹纸

小白月赛三 妹纸

题目链接:https://www.nowcoder.com/acm/contest/87/D
来源:牛客网
题目描述
XHRlyb发明了一类数,叫做妹纸数。
假设xi∈[p,q],yi∈[u,v],且xi与yi均为整数,我们称这区间[p,q]相对于区间[u,v]的妹纸数为
∑ i = p q = i   m o d   v   m o d   ( v − 1 )   m o d …   m o d   ( u ) \sum_{ i=p }^ { q } = i~ mod~ v~mod~(v-1)~mod…~mod~(u) i=pq=i mod v mod (v1) mod mod (u)
XHRlyb想让Cwbc帮她快速计算多组区间(a,b]相对于区间[l,r)的妹纸数。
Cwbc显然是愿意帮助她的,但他知道你不想解决这个问题,于是就把这个问题交给了你。
聪明的你在仔细阅读题目后,一定可以顺利的解决这个问题!
输入描述:
输入数据有多行,每行有四个整数,a,b,l,r。
输出描述:
输出数据应有多行,每行有一个数,表示答案。
示例1
输入
复制
2 3 1 2
输出
0
说明
任何数对1取模后的结果都为0。
示例2
输入
3 6 2 4
输出
1
备注:
a ≤ b,l ≤ r。
a,b,l,r∈[1,10^6]。
1 ≤ 数据组数 ≤ 1000。

解题思路:
对于区间求和的问题我们可以把它转化为求差值来算:比如我们要求自然数5-10的和sum,我们就可以把它转化为先求1-10的和记作sumA,再求1-4的和记作sumB,然后sum=sumA-sumB,显然我们也可以把这道题转化成这种形式,因为题中要求的区间为(a,b],所以我们可以先求出1–p对于区间[l,r)求余的和,在求出1–q区间[l,r)求余的和,然后做差即可。显然对于求1–p和1–q对于区间区间[l,r)求余的和是一个难题,其实仔细想一想就能得出一个结论:一个数对于一个左闭右开的区间[l,r)求余的到的最大的数就是L-1。因为区间的不确定性,还分为两种情况:1.若x<r,则需要判断x%(r)与(L)的大小并求出最小值minn。在求1—minn的和。2.若x>=r,则直接算出1—L的和sum在乘以x/r,然后在加上情况1(因为x/r不一定被整除,不被整除的话x/r的余数正好符合情况1)

因为刚开始写博客,还不能较好的把自己的想法表达出来,若有一些语句表达不当,请留言指出。
AC代码:

#include <iostream>
using namespace std;
typedef long long LL;
LL a,b,l,r;
LL Sum(LL x) {//计算1---x的和
    return x*(x+1)>>1;
}
LL solve(LL x) {
    return Sum(l)*(x/r)+Sum(min(x%r,l));//因为x<r的时候x/r等于0,所以可以把两种情况写到一起。
}
int main() {
    while (cin>>a>>b>>l>>r) {
        l--,r--;//因为区间是左闭右开所以对于l求余的最大值即为l-1,r--是表示r能取到的最大值
        cout<<(solve(b)-solve(a))<<endl;
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值