E. Calendar Ambiguity(思维&数论)
思路:思维&数论。
考虑
i月
j日
=j月
i日。
即:
{[(i−1)×d+j]−[(j−1)×d+i]}(modw)=0。
(d−1)(i−j)(modw)=0,(j<i)
令
g=gcd(d−1,w)。
我们只需
(i−j)为
gw的倍数即可。
令
w′=gw
因为可能存在
i月
j日,而不存在
j月
i日。
所以取
m=min(n,d),
i≤m,保证存在这样的一对。
考虑枚举不同
i的贡献。
当
i=m,贡献为:
w′m−1
当
i=m−1,贡献为:
w′m−2
…
总贡献为:
w′m−1+w′m−2+⋯+ww。
这里都是作向下取整运算。
即答案的形式肯定是:
1,1,…,2,2,2…,3,3….
我们令:
x=w′m−1,我们只需找到
x有多少个,剩下的
x−1,x−2…,3,2,1都是
w′个。
令
y=w′m−1(modw)+1 ,即为
x的个数。
然后答案就是:
y×x+2(x−1)x×w′
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
ll n,d,w;
scanf("%lld%lld%lld",&n,&d,&w);
w/=gcd(d-1,w);
ll m=min(n,d)-1;
ll x=m/w,y=m%w+1;
printf("%lld\n",y*x+(x-1)*x/2*w);
}
return 0;
}