NPY and girls 莫对算法 乘法逆元

  

题意:拜访n个女生,每个女生属于一个班级,每次只能访问一个班的一个女生,问访问所有女生有多少种顺序(顺序指的是班级顺序)

假设有n个女生,分别属于m个班级,每个班级有num(i)个女生,那么访问的种数就是n!/(num1!*num2!*...numm!),

运用了乘法逆元解决除法的情况

但是有一个巨大的坑点:

    while (L < Q[i].l) del(L),L++;
            while (L > Q[i].l) --L,add(L);

            while (R < Q[i].r) ++R,add(R);
            while (R > Q[i].r) del(R),R--;
这样写就会wa

把R放在上面才能ac

转移的时候先更新右端点 再更新左端点  不然可能出现右端点在左端点左边的情况(可能导致wa)  

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=30000+10;
const ll mod=1000000007;
ll a[N],cnt[N],ans[N],fac[N],inv[N],n,L,R,num=1,block,m,l,r;

ll fast(ll x, ll n)
{
    ll ans=1;
    while(n)
    {
        if(n&1)ans=(ans*x)%mod;
        x=(x*x)%mod;
        n>>=1;
    }
    return ans%mod;
}
void init()
{
    fac[1]=fac[0]=1;
    inv[0]=inv[1]=1;
    rep(i,2,30000+5)
    {
        fac[i]=fac[i-1]*i%mod;
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    }
}
void add(int x)
{
    cnt[a[x]]++;
    num=num*cnt[a[x]]%mod;
}
void del(int x)
{
    num=num*inv[cnt[a[x]]]%mod;
    cnt[a[x]]--;
}
struct node
{
    ll l,r,block;int id;
}s[N];
bool cmp(node a,node b)
{
    return a.l/block==b.l/block?a.r<b.r:a.l<b.l;
}
int main()
{
    init();
    int cas;RI(cas);
    while(cas--)
    {
        CLR(cnt,0);
        cin>>n>>m;
        block=sqrt(n);
        rep(i,1,n)scanf("%lld",&a[i]);
        rep(i,1,m)scanf("%lld%lld",&s[i].l,&s[i].r),s[i].id=i,s[i].block=(s[i].l-1)/block+1;

        sort(s+1,s+1+m,cmp);
        L=1,R=1,num=1;
        cnt[a[1]]=1;
        rep(i,1,m)
        {
            l=s[i].l,r=s[i].r;
            while(R<r)add(++R);
            while(R>r)del(R--);

            while(L<l)del(L++);
            while(L>l)add(--L);

            ans[s[i].id]=fac[r-l+1]*fast(num,mod-2)%mod;
        }
        rep(i,1,m)printf("%lld
",ans[i]%mod);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/10965352.html