CCA's ball (combination mathematics + principle of tolerance and exclusion)

https://ac.nowcoder.com/acm/contest/11168/D


Given n small balls, each of which has a color, put them in a row.

The two schemes are different. If and only if there is a certain position, the colors of the balls placed in this position of the two schemes are different.
A scheme is legal, if and only if there are no two adjacent balls with the same color, find the value of the number of legal schemes modulo 10^9+7.


First consider taking the negative calculation. Consider "the two schemes are different, and if and only if there is a certain position, the colors of the balls placed in this position of the two schemes are different." How to calculate the total number of schemes.

We directly do not have any restriction is fac[n], but there can be no two positions with the same color. When we use fac to calculate, the two colors of B, namely B1 and B2, are counted as two different schemes. Actually the same. So for all the number of schemes in fac[n], B1 and B2 have the repetition of the total number of schemes of fac[2] (2X1), so the total number of schemes is (cnt represents the number of colors 2) fac[n]/ (2^cnt)

Then repeat up to 5e5 in total. We consider tolerance. Mark si as the existence of two adjacent balls with the same color.

ans=total-| s1∪s2∪s3......∪scnt|

That is, subtract s1, s2, s3...scnt,

Add s1∩s2, s1∩s3...

 

Consider how to find only one pair of different colors. First, there are C(m,1) kinds of selection methods for a pair. Since the condition is adjacent positions, we bind the pair of balls of the same color. Then there are ni balls left at this time, the whole arrangement is fac[ni], then at this time, the state of other colors that meet the first condition should be considered, fac[ni]/(2^(cnt-1) [Same as the legal total number at the beginning]

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<unordered_map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e6+100;
typedef long long LL;
const LL mod=1e9+7;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL fac[maxn],inv[maxn],inv1[maxn];
LL a[maxn];
unordered_map<LL,LL>map1;
LL ksm(LL a,LL k){
    LL res=1;
    while(k>0){
        if(k&1) res=res*a%mod;
        k>>=1;
        a=a*a%mod;
    }
    return res%mod;
}
void init(){
    fac[0]=1;
    for(LL i=1;i<maxn-10;i++) fac[i]=fac[i-1]*i%mod;
    inv[0]=1;
    for(LL i=1;i<maxn-10;i++) inv[i]=inv[i-1]*ksm((LL)i,mod-2)%mod;
    inv1[0]=1;
    for(LL i=1;i<maxn-10;i++) inv1[i]=inv1[i-1]*ksm((LL)2,mod-2)%mod;
}
LL C(LL n,LL m){
   return (fac[m]%mod*inv[n]%mod*inv[m-n]%mod)%mod;
}
int main(void)
{
  init();
  LL n;n=read();
  LL cnt=0;
  for(LL i=1;i<=n;i++){
    a[i]=read();
    if(map1.count(a[i])){
        cnt++;
    }
    else map1[a[i]]=1;
  }
  LL ans=(fac[n]%mod*inv1[cnt]+mod)%mod;

  for(LL i=1;i<=cnt;i++){
      if(i&1){
         ans=(ans%mod-C(i,cnt)%mod*fac[n-i]%mod*inv1[cnt-i]%mod+mod)%mod;
      }
      else{
         ans=(ans%mod+C(i,cnt)%mod*fac[n-i]%mod*inv1[cnt-i]%mod+mod)%mod;
      }
      ans=(ans+mod)%mod;
  }
  printf("%lld\n",ans);
return 0;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/115112046