題目鏈接:http://codeforces.com/contest/1389/problem/E
大概題意:某個國家一年有m個月,每個月有d天,一個星期有w天。(x,y)且(x<y),表示x月y天,如果x月y天和y月x天是一周中的同一天,則(x,y)是好的,問你第一年中有多少個好的。
思路:a月b號和b月a好如果是一周的同一天,那(b-1)*d+a-( (a-1)*d+b)取模w要為0才行,化簡得 (b-a)(d-1) 取模w要為0,設c=b-a,c為兩個月份之差,那c*(d-1)%w==0,先讓(d-1)取模下w, x=(d-1)%w; 如果x=0的話,那c為任意正整數都可以 ,那ans=md*(md-1)/2, md=min(m,d)。m和d要取個最小的,比如m=10,d=7,有10月7號,但沒有7月10號,(我就是忘取最小的了,樣例都過不了,我還以為其他地方有bug)。如果x!=0,那c只要是 lcm(w,x)/x 的正整數倍即可,設y=lcm(w,x)/x,那ans=(md-1)/y + (md-2)/y + (md-3)/y+........。然后再處理下這個就可以了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll fun(ll x,ll y)
{
while(y)
{
ll z=x%y;
x=y;
y=z;
}
return x;
}
int main()
{
int T;
cin>>T;
while(T--)
{
ll m,d,w;
cin>>m>>d>>w;
ll md=min(m,d);//月數和每月的天數要取較小的
ll x=(d-1)%w;
if(x==0)//月份之差可以為任意正整數
{
cout<<md*(md-1)/2<<endl;
continue;
}
ll y=x*w/fun(w,x);//最小公倍數
y=y/x;//月份之差必須為y的倍數
//答案就是 (md-1)/y + (md-2)/y + (md-3)/y+........
ll xx=(md-1)/y;
ll yy=xx-1;
ll ans=yy*(yy+1)/2;
ans*=y;
ll zz=(md-1)%y;
zz++;
ans=ans+xx*zz;
cout<<ans<<endl;
}
}
