2751: [HAOI2012]容易题(easy)|快速幂

很显然就是每一个位置可以取得数字之和都乘起来
然后限制并不多,也就是说大部分位置上的数字之和是相同的,然后用快速幂单独把这些的乘积搞出来,然后再单独算那些有限制的位置。
PS: 限制可能有重复,所以要特判一下,不过样例良心给了重复的

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define ll long long
#define mod 1000000007
using namespace std;
int sc()
{
    int i=0,f=1; char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i*f;
}
struct W{int x,y;}a[100005];
int n,m,k;
ll sum,ans;
bool cmp(W x,W y)
{
    return x.x==y.x?x.y<y.y:x.x<y.x;
}
ll cal(ll x,ll y)
{
    ll ans=1;
    for(;y;x=x*x%mod,y>>=1)
        if(y&1)ans=ans*x%mod;
    return ans;
}
int main()
{
    n=sc(),m=sc(),k=sc();
    for(int i=1;i<=k;i++)
        a[i].x=sc(),a[i].y=sc();
    sort(a+1,a+k+1,cmp);
    for(int i=1;i<=k;i++)
        if(a[i].x!=a[i-1].x)m--;
    sum=(ll)n*(1+n)/2%mod;
    ans=cal(sum,m);
    for(int i=1,last;i<=k;i=last)
    {
        ll now=sum;
        for(last=i;a[last].x==a[i].x;last++)
            if(last==i||a[last].y!=a[last-1].y)
            now=(now-a[last].y+mod)%mod;
        ans=ans*now%mod;
    }
    cout<<ans;
    return 0;
}

你可能感兴趣的:(快速幂)