HDU 4710 Balls Rearrangement(数论)
2013-09-12 20:03
323 查看
根据题意:求sum(|i%a-i%b|)=?,i=[1->N];
分析:
首先一个很显然的规律,这是一个循环节的求余问题,L=Lcm(a,b)为一次循环。讨论一个循环:
a=4 b=2
0 1 2 3 0 1 2 3
0 1 0 1 0 1
0 1
a=3 b=4
0 1 2 0 1 2 0 1 2 0 1 2
0 1 2 0
0 1 2 3 0 1 2 3 0 1 2 3
0 1 2 3
此题关键是怎样发现求|i%a-i%b|,先可以忽略重复的。一个很重要的是如果在某一个位置i,在a中的序列,和在b中的序列是同时递增到j,那么,它的值之和刚好等于第一个两个数之差乘以该连续递增的长度,即:
|i%a-i%b|+.....|j%a-j%b|=(j-i+1)*|i%a-i%b|
比如蓝色的数字sum=2*(1-0)=2,类似的还有很多。
那么怎样保持是递增的呢?,不可能每次去找,这样算法反而变复杂了,其实并不难,在i和j都属于min(a,b)的序 列中本身就是递增的。(i+len)在a范围内,(j+len)在b范围内。
代码:
分析:
首先一个很显然的规律,这是一个循环节的求余问题,L=Lcm(a,b)为一次循环。讨论一个循环:
a=4 b=2
0 1 2 3 0 1 2 3
0 1 0 1 0 1
0 1
a=3 b=4
0 1 2 0 1 2 0 1 2 0 1 2
0 1 2 0
0 1 2 3 0 1 2 3 0 1 2 3
0 1 2 3
此题关键是怎样发现求|i%a-i%b|,先可以忽略重复的。一个很重要的是如果在某一个位置i,在a中的序列,和在b中的序列是同时递增到j,那么,它的值之和刚好等于第一个两个数之差乘以该连续递增的长度,即:
|i%a-i%b|+.....|j%a-j%b|=(j-i+1)*|i%a-i%b|
比如蓝色的数字sum=2*(1-0)=2,类似的还有很多。
那么怎样保持是递增的呢?,不可能每次去找,这样算法反而变复杂了,其实并不难,在i和j都属于min(a,b)的序 列中本身就是递增的。(i+len)在a范围内,(j+len)在b范围内。
代码:
#include<iostream> #include<cstdio> #include<cstring> typedef __int64 INT; using namespace std ; INT Gcd(INT x,INT y){ if(y==0) return x; return Gcd(y,x%y); } INT Lcm(INT x,INT y){ return (x*y)/Gcd(x,y); } inline INT val(INT x,INT y){ if(x<y) return y-x; return x-y; } inline INT min(INT x,INT y){ return x<y?x:y; } INT calc(INT a,INT b,INT n) { INT x=0,y=0,i=0,L; INT ret=0; while(i<n){ L=min(a-x,b-y); if(i+L>n) L=n-i; // printf("%I64d %I64d %I64d\n",L,x,y); ret+=L*val(x,y); x=(L+x)%a; y=(L+y)%b; i+=L; } return ret; } int main() { INT n,a,b,m,ans; int T; scanf("%d",&T); while(T--){ scanf("%I64d%I64d%I64d",&n,&a,&b); m=Lcm(a,b); if(n<=m) ans=calc(a,b,n); else ans=calc(a,b,m)*(n/m)+calc(a,b,n%m); printf("%I64d\n",ans); } return 0 ; }
相关文章推荐
- hdu 4710 Balls Rearrangement 数论
- hdu 4611/4710 Balls Rearrangement 数论
- hdu 4710 Balls Rearrangement 数论
- HDU 4710 && HDU 4611 Balls Rearrangement (热身赛第五题)
- hdu 4710 Balls Rearrangement()
- hdu 4710 Balls Rearrangement (数学思维)
- hdu 4710 Balls Rearrangement
- 数学 之 hdu 4710 Balls Rearrangement
- hdu 4710 Balls Rearrangement
- hdu - 4710/4611 - Balls Rearrangement
- HDU 4710 Balls Rearrangement
- 数学 之 hdu 4710 Balls Rearrangement
- HDU 4710 Balls Rearrangement (纯数学)
- HDU - 4710 Balls Rearrangement
- HDU 4611--Balls Rearrangement--数论找出循环节+跳跃求值
- hdu 4710 Balls Rearrangement (数学思维)
- HDU 4710 Balls Rearrangement
- HDU 4710 Balls Rearrangement
- [hdu 4611]Balls Rearrangement 数论
- HDU 4710 Balls Rearrangement