zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    机器学习---聚类算法
    机器学习解决问题的框架
    17个机器学习的常用算法!
    机器学习---理论篇
    golang 调用cmd执行EXE
    队列(自定义列表实现自定义队列)
    栈Stack(使用自定义链表实现自定义栈)
    链表( 自定义链表)
    队列(动态数组实现自定义队列)
    栈Stack(动态数组实现自定义栈)
  • 原文地址:https://www.cnblogs.com/bxd123/p/10965352.html
Copyright © 2011-2022 走看看