AtCoder Beginner Contest 172 E - NEQ ###K ###K //K
题目链接:https://atcoder.jp/contests/abc172/tasks/abc172_e
题意:给定两个数n m 数为1~m之间 构造一段长度为n的序列 要求满足 所有i Ai!=Bi
并且 Ai!=Aj Bi!= Bj 问有多少种方案 mod 1e9+7
首先如果两个序列一起确定 用A(n,m)*A(n,m) 减去不合格的情况 这种做法不可行, 因为同时确定2个序列 无法用上容斥原理了
那么考虑先确定 第一个序列(A序列) 即有A(n,m) 种情况, 那么只需要求出第二个序列(B)的合法情况 两者相乘即可
B的要求的即是 不合法的 那么就有 1个位置不合法的 2个位置不合法的 …… n个位置不合法的 这样求的过程中 假设我要求 1个不合法的位置,但很难确保其他不合法
所以 我们可以考虑 至少i个不合法 所以求的 1个不合法就是 只要有一个不合法的就行 ,这样就会重复的求 比如求一个不合法的时候 两个不合法的位置也被求了 所以要用到了容斥原理
根据奇加偶减的原则 我们就可以求出这样的总的不重复的不合法数 类比容斥原理最基本的题型 求 不是2 3 5 的 倍数 那么此时的1个不重复的位置 就相当于 求出n/2 n/3 n/5 并加上
而求两个位置不重复的数就相当于 求出 n/6 n/10 n/15 并减去
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define pb push_back 6 const int maxn=5e5+10; 7 const int mod=1e9+7; 8 ll inv[maxn]; 9 ll fac[maxn]; 10 ll power(ll base,ll n) 11 { 12 ll r=1; 13 while(n) 14 { 15 if(n&1) r=r*base%mod; 16 base=base*base%mod; 17 n/=2; 18 } 19 return r; 20 } 21 void init() 22 { 23 fac[0]=1; 24 for(int i=1;i<maxn;i++) 25 { 26 fac[i]=fac[i-1]*i%mod; 27 } 28 inv[maxn-1]=power(fac[maxn-1],mod-2); 29 for(int i=maxn-2;i>=0;i--) 30 { 31 inv[i]=inv[i+1]*(i+1); 32 inv[i]%=mod; 33 } 34 35 } 36 ll C(ll m,ll n) 37 { 38 return fac[n]*inv[m]%mod*inv[n-m]%mod; 39 } 40 ll A(ll m,ll n) 41 { 42 return fac[n]*inv[n-m]%mod; 43 } 44 45 46 int main() 47 { 48 ios::sync_with_stdio(false); 49 cin.tie(0); 50 init(); 51 ll n,m; 52 cin>>n>>m; 53 ll sum=A(n,m); 54 ll res=0; 55 int f=-1; 56 for(int i=1;i<=n;i++) 57 { 58 f*=-1; 59 res+=C(i,n)*A(n-i,m-i)%mod*f; 60 res=(res+mod)%mod; 61 } 62 res=(sum-res+mod)%mod; 63 ll ans=sum*res%mod; 64 cout<<ans<<'\n'; 65 66 67 68 69 }

浙公网安备 33010602011771号