a
题目描述:
输入:
从文件a.in中读入数据。
第丬行两个整数n, m,意义见问题描述。
接下来m行,第i行三个整数x, y, z,表示第i个坑的坐标(x, y, z)。
输出:
输出到文件a.out中
一个整数,即答案。
这道题就是一到改编题,然后思想和原来那道题一样。
这里就不多讲了,直接贴代码吧。
就是设
表示到第
个坑,且不经过其他坑的方案数。
就这样啊。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 100010;
const int mod = 1000000007;
inline void read(ll &x)
{
char ch = getchar(); x = 0;
for(;ch < '0' || ch > '9';) ch = getchar();
for(;ch >= '0' && ch <= '9';) x = x * 10 + (ch ^ '0'), ch = getchar();
}
struct node{ ll x,y,z; } p[N];
int n,k,cnt = 0;
ll fac[N * 3] = {1},inv[N * 3] = {1},f[N];
bool cmp(node a,node b) { return a.x < b.x || (a.x == b.x && a.y < b.y) || (a.x == b.x && a.y == b.y && a.z < b.z);}
ll f_pow(ll a,int x)
{
ll ret = 1;
for(;x;x >>= 1) (x & 1) && (ret = 1ll * ret * a % mod), a = a * a % mod;
return ret % mod;
}
ll C(ll x,ll y,ll z) { return 1ll * fac[x + y + z] * inv[x] % mod * inv[y + z] % mod * fac[y + z] % mod * inv[y] % mod * inv[z] % mod; }
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d%d",&n,&k);
for(int i = 1;i <= k; ++ i)
read(p[i].x), read(p[i].y), read(p[i].z), ++cnt;
p[++cnt] = (node){ n,n,n }; sort(p + 1,p + 1 + cnt,cmp);
for(int i = 1;i < N * 3; ++ i)
fac[i] = fac[i - 1] * 1ll * i % mod, inv[i] = 1ll * f_pow(fac[i],mod - 2);
for(int i = 1;i <= cnt; ++ i)
{
f[i] = 1ll * C(p[i].x,p[i].y,p[i].z);
for(int j = 1;j < i; ++ j)
if(p[i].x >= p[j].x && p[i].y >= p[j].y && p[i].z >= p[j].z)
f[i] = (f[i] - 1ll * C(p[i].x - p[j].x,p[i].y - p[j].y,p[i].z - p[j].z) * f[j] % mod + mod) % mod;
}
printf("%lld",(f[cnt] + mod) % mod);
fclose(stdin); fclose(stdout);
return 0;
}