题目描述
在三维空间中,平面 x = 0, y = 0, z = 0,以及平面 x + y + z = K 围成了一个三棱锥。
整天与整数打交道的小明希望知道这个三棱锥内、上整点的数目。
他觉得数量可能很多,所以答案需要对给定的 M 取模。
整天与整数打交道的小明希望知道这个三棱锥内、上整点的数目。
他觉得数量可能很多,所以答案需要对给定的 M 取模。
输入描述:
输入有 1 ≤ T ≤ 105 组数据。 每组数据中,输入两个整数 0 ≤ K ≤ 109 + 7, 1 ≤ M ≤ 109 + 7,意义如题目描述。
输出描述:
对于每组数据,输出一个整数,为三棱锥内、上整点的数目对 M 取模。
示例1
输入
4 0 60 1 60 29 60 29 100007
输出
1 4 40 4960
题意:就是给你找出x + y + z <= k的正整数点的个数。。。
思路:这个题目卡了好久,一直没有推出公式来,幸好yhc是个数论大佬,才险些签到。。。
公式: f = (x + 1)*(x + 2)*(x + 3)/6 ;
怎么推出来的呢????
首先我们的知道一个重要公式:
- 证明:
- 代码就很简单了。。。。直接暴力也不用逆元。。
#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
int n, m, k, t;
ll lpow(ll a, ll b) {
ll ans = 1;
while(b) {
if(b&1) ans = ans*a%m;
a = a*a%m;
b >>= 1;
}
return ans;
}
int main()
{
scanf("%d", &t);
while(t--) {
scanf("%d%d", &k, &m);
ll a = k+1, b = k+2, c = k+3, ans = 0;
if(a%2 == 0) a /= 2;
else if(b%2 == 0) b /= 2;
else if(c%2 == 0) c /= 2;
if(a%3 == 0) a /= 3;
else if(b%3 == 0) b /= 3;
else if(c%3 == 0) c /= 3;
ans = ((a*b%m)*c)%m;
cout << ans << endl;
}
return 0;
}