9.5upc组队训练赛
D题
题面
题目描述
You are given multiple problems with three integers p, q, and n. Find . That is, the first n multiples of p, modulo q, summed. Note that the overall sum has no modulus.
输入
Each input will begin with a line with a single integer W (1≤W≤105 ), which is the number of cases you must solve.
Each of the next W lines will contain three space-separated integers p, q and n (1≤p, q, n≤106 ),which are the parameters of the problem as described above.
输出
Output W lines, each with the answer for a given instance of the problem, in the order that they appear in the input.
样例输入
3
2 7 2
1 4 5
3 8 10
样例输出
6
7
37
思路
先写了个暴力计算,T掉 这是一道类欧几里德模板模板题,在网上搜到了公式,a%b=a-a/b (a整除b) b;则原式=an*(n+1)/2-(
∑
i
=
1
n
(
p
∗
i
)
/
q
\displaystyle \sum^{n}_{i=1}{(p*i)/q}
i=1∑n(p∗i)/q)*q
利用fun计算
∑
i
=
1
n
(
p
∗
i
)
/
q
\displaystyle \sum^{n}_{i=1}{(p*i)/q}
i=1∑n(p∗i)/q,推导很复杂,me没看懂,直接套用函数……
源码
#include <iostream>
using namespace std;
typedef long long ll;
ll fun(ll a, ll b,ll c,ll n){
if(n==1)return (b/c);
else if(n<=0)return 0;
ll tmp=0;
tmp+=(a/c)*((n-1)*n/2);
tmp+=(b/c)*n;
a%=c;
b%=c;
if(a==0) return tmp;
else return (tmp+fun(c,(a*n+b)%c,a,(a*n+b)/c));
}
int main(int argc, char** argv) {
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--){
ll p,q,n,i,sum=0,j=0;
cin>>p>>q>>n;
sum+=p*n*(n+1)/2ll;
sum-=q*fun(p,p,q,n);
cout<<sum<<'\n';
}
return 0;
}
/*
3
2 7 2
1 4 5
3 8 10
*/