Loading

容易题(数论)

容易题

题目大意

有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的数列的积的和mod 1000000007的值,是不是很简单呢?呵呵!

solution

容易题
根据我们数学刚刚学的分步乘法原理
没有限制的话那么总的方案数量\((1+2+3+……+n)^m\)
记录一下不能取到的值的\(tot\)
然后统计答案的时候把这个值换成\({\frac{(n(n-1))}{2}}\)\(-tot\)
对于剩下的点\(({\frac{(n(n-1))}{2}})^{m-cnt}\)
用快速幂预处理一下,然后累乘出结果就行了

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define int long long
using namespace std;
const int mod=1e9+7;
const int maxn=100005;
int sum[maxn];

struct node{
    int x,y;
}a[maxn];

inline int read(){
    int x=0,w=1;
    char ch=getchar();
    for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    return x*w;
}

inline bool cmp(node a,node b){
    if(a.x==b.x)
        return a.y<b.y;
    else 
        return a.x<b.x;
}

inline int power(int x,int y,int mod){
    int res=1;
    while(y){
        if(y&1)
            res=res*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return res;
}
int n,m,k;

signed main(){
    int ans=0;
    n=read(),m=read(),k=read();
    int sigma=(n*(n+1)>>1)%mod;
    for(int i=1;i<=k;i++)
        a[i].x=read(),a[i].y=read();
    sort(a+1,a+1+k,cmp);
    int cnt=0;
    for(int i=1;i<=k;i++){
        if(a[i].x!=a[i-1].x)
            sum[++cnt]=sigma;
        else
            if(a[i].y==a[i-1].y)
                continue;
        sum[cnt]=(sum[cnt]-a[i].y+mod)%mod;
    }
    ans+=power(sigma,m-cnt,mod);
    for(int i=1;i<=cnt;i++)
        ans=(ans*sum[i]+mod)%mod;
    cout<<ans<<'\n';
    return 0;
}
posted @ 2020-05-14 17:47  Gary_818  阅读(131)  评论(0编辑  收藏  举报