【BZOJ2751】【codevs1853】容易题,快速幂+逆元

Time:2016.06.24
Author:xiaoyimi
转载注明出处谢谢



传送门1
传送门2
思路:
k=0时答案就是
mi=1nj=1j
=(n(n+1)2)m
每一种限制条件就是在乘的时候去除某个数
就比如说n=3,m=3时,答案就是
(1+2+3)(1+2+3)(1+2+3)=216
当k=1,限制条件为(1,1)时我们就把第一个括号里的1去掉,变成
(2+3)(1+2+3)(1+2+3)=180
k=2,限制条件为(1,1)(2,1)时答案就是
(2+3)(2+3)(1+2+3)=150
搞清楚这个原理接下来就很简单了
将k个限制条件排序,然后分开计算每一个位置里的数就好了,剩下的没被去掉的位置用快速幂
(思想如上,但代码表达上有点怪,仅供参考)

#include<cstdio>
#include<iostream>
#include<algorithm>
#define M 100004
#define LL long long
#define mo 1000000007
using namespace std;
int in()
{
    int t=0;char ch=getchar();
    while (ch>'9'||ch<'0') ch=getchar();
    while (ch>='0'&&ch<='9') t=(t<<3)+(t<<1)+ch-48,ch=getchar();
    return t;
}
LL qr(LL x,int y)
{
    LL ans=1;
    for (;y;y>>=1,x=x*x%mo)
        if (y&1) ans=ans*x%mo;
    return ans;
}
int n,m,k;
struct node{
    int x,y;
    bool operator <(node other)const{
        if(x!=other.x) return x<other.x;
        return y<other.y;
    } 
}Q[M];
LL ans,sum,inv;
main()
{
    n=in();m=in();k=in();
    for (int i=1;i<=k;i++)
        Q[i].x=in(),Q[i].y=in();
    LL nn=(LL)n*(n+1)/2%mo; 
    ans=qr(nn,m);
    inv=qr(nn,mo-2);
    sort(Q+1,Q+k+1);
    sum=Q[1].y;
    for (int i=2;i<=k;i++)
    {
        if (Q[i].x==Q[i-1].x)
            if (Q[i].y!=Q[i-1].y) sum+=Q[i].y;
            else;
        else
            ans=ans*(nn-sum)%mo*inv%mo,
            sum=Q[i].y;
    }
    ans=ans*(nn-sum)%mo*inv%mo;
    printf("%d",ans<0?ans+mo:ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值