HDU 5970 CCPC2016合肥 求等差数列整除整数下取整求和
先来大宝贝
a 公差
b 初始项
c 除数
n 项数
long long get(long long a,long long b,long long c,long long n){ if (n<=0) return 0; if (n==1) return (b/c) % mod; long long tmp = 0; tmp += (a/c)%mod*((n-1)*n/2%mod)%mod; tmp %= mod; tmp += (b/c)*(n)%mod; tmp %= mod; a = a%c; b = b%c; if (a==0) return tmp; else return (tmp+get(c,(a*n+b)%c,a,(a*n+b)/c)) % mod; }
例题
HDU 5970
代码
#include <bits/stdc++.h> long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std; long long c; int f(int x,int y) { c = 0; int t; while (y>0) { c +=1; t = x % y; x = y; y = t; } return x; } long long get(long long a,long long b,long long c,long long n){ if (n<=0) return 0; if (n==1) return (b/c) % mod; long long tmp = 0; tmp += (a/c)%mod*((n-1)*n/2%mod)%mod; tmp %= mod; tmp += (b/c)*(n)%mod; tmp %= mod; a = a%c; b = b%c; if (a==0) return tmp; else return (tmp+get(c,(a*n+b)%c,a,(a*n+b)/c)) % mod; } long long F(long long x, long long y){ long long ans = 0; for (long long i = 1; i <= y ; i++){ for (long long j = 0; j<i; j++){ if (j==0&&i!=1) continue; long long a = j; if ( a == 0 ) a = 1; long long b = i; if (f(a,b) == 1){ long long n = (x-a)/b + 1; a = a*b; b = b*b; ans = (ans + get(b,a,c,n)) % mod; } } } return ans; } int main() { int T; cin >> T; while (T--){ long long x; long long y; long long p; scanf("%I64d%I64d%I64d",&x,&y,&p); mod = p; long long ans = 0; for (int i = 1 ; i <= y ; i++){ ans = (ans + F(x/i,y/i)) % mod; } printf("%I64d\n",ans); } return 0; }