JZOJ6403【NOIP2019模拟11.04】a

a

题目描述:在这里插入图片描述

输入:
从文件a.in中读入数据。
第丬行两个整数n, m,意义见问题描述。
接下来m行,第i行三个整数x, y, z,表示第i个坑的坐标(x, y, z)。

输出:
输出到文件a.out中
一个整数,即答案。

这道题就是一到改编题,然后思想和原来那道题一样。

这里就不多讲了,直接贴代码吧。

就是设 f i f_{i} 表示到第 i i 个坑,且不经过其他坑的方案数。
就这样啊。

#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;
}

猜你喜欢

转载自blog.csdn.net/INnovate2030/article/details/102894532
今日推荐