• BZOJ 2751: [HAOI2012]容易题(easy) 数学


    2751: [HAOI2012]容易题(easy)

    题目连接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=2751

    Description

    为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下:
    有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的数列的积的和 mod 1000000007的值,是不是很简单呢?呵呵!

    Input

    第一行三个整数n,m,k分别表示数列元素的取值范围,数列元素个数,以及已知的限制条数。
    接下来k行,每行两个正整数x,y表示A[x]的值不能是y。

    Output

    一行一个整数表示所有可能的数列的积的和对1000000007取模后的结果。如果一个合法的数列都没有,答案输出0。

    Sample Input

    3 4 5

    1 1

    1 1

    2 2

    2 3

    4 3

    Sample Output

    90

    样例解释

    A[1]不能取1

    A[2]不能去2、3

    A[4]不能取3

    所以可能的数列有以下12种

    数列 积

    2 1 1 1 2

    2 1 1 2 4

    2 1 2 1 4

    2 1 2 2 8

    2 1 3 1 6

    2 1 3 2 12

    3 1 1 1 3

    3 1 1 2 6

    3 1 2 1 6

    3 1 2 2 12

    3 1 3 1 9

    3 1 3 2 18

    Hint

    题意

    题解:

    答案显然是每个位置的数可选的数的和的累积(即PI(sigma(j)))

    然后我们可以暴力处理出有限制的地方的乘积

    然后再快速幂搞定剩下没有限制的乘积就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+8;
    const int mod = 1e9+7;
    long long pow_mod(long long a,long long n,long long mod)
    {
         long long ret = 1;
         long long temp = a%mod;
         while(n)
         {
             if(n & 1)ret = ret*temp%mod;
             temp = temp*temp%mod;
             n >>= 1;
         }
         return ret;
    }
    long long n,m;
    int k;
    vector<pair<int,int> >p;
    map<int,long long> H;
    int main()
    {
        scanf("%lld%lld%d",&n,&m,&k);
        for(int i=0;i<k;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            p.push_back(make_pair(x,y));
        }
        sort(p.begin(),p.end());
        p.erase(unique(p.begin(),p.end()),p.end());
        for(int i=0;i<p.size();i++)
        {
            H[p[i].first]=(H[p[i].first]+p[i].second)%mod;
        }
        map<int,long long>::iterator it;
        int tot = 0;
        long long ans = 1;
        long long temp = (1LL+n)*n/2LL%mod;
        for(it=H.begin();it!=H.end();it++)
        {
            tot++;
            ans = ans*(temp-it->second)%mod;
            if(ans<0)ans+=mod;
        }
        ans = ans * pow_mod(temp,m-tot,mod)%mod;
        if(ans<0)ans+=mod;
        printf("%lld
    ",ans);
    }
  • 相关阅读:
    C# 对Excel文档打印时的页面设置
    C# 对Excel 单元格格式, 及行高、 列宽、 单元格边框线、 冻结设置
    object does not contain a definition for get_range
    shell变一些小技巧
    Codeforces Round #277.5 (Div. 2)A——SwapSort
    ActiveMQ与RabbitMQ采用camel综合
    SAP ABAP规划 使用LOOP READ TABLE该方法取代双LOOP内部表的方法
    Object-c中间initialize 与 辛格尔顿
    队列——阵列实现
    左右GNU Linux企业加密文件系统 eCryptfs简介
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5179499.html
Copyright © 2020-2023  润新知