当前位置:网站首页>775 Div.1 C. Tyler and strings combinatorial mathematics

775 Div.1 C. Tyler and strings combinatorial mathematics

2022-07-05 04:45:00 Strezia

C
Combinatorial mathematics ,1900, Array of numbers

The question

give s , t s, t s,t Two sequences , The lengths are n , m n,m n,m, ask s s s How many sorting methods meet s s s The dictionary order of t t t Small . 1 ≤ n , m ≤ 2 e 5 1\leq n,m\leq 2e5 1n,m2e5

Ideas

Because it is compared in dictionary order , So if s 1 < t 1 s_1<t_1 s1<t1 After that, you can row at will , So before considering enumeration i − 1 i-1 i1 The bits are the same and s i < t i s_i<t_i si<ti The sorting methods of are c n t i cnt_i cnti Kind of , The final answer is ∑ i = 1 i = n c n t i \sum_{i=1}^{i=n} cnt_i i=1i=ncnti .

So how to ask c n t i cnt_i cnti Well ? If repeatable arrangement is not considered , that c n t i = n o w × ( n − i ) ! cnt_i= now \times (n-i)! cnti=now×(ni)! , namely To the first i Bit current Satisfaction is less than t i t_i ti Multiply the number of by the total arrangement of the following numbers ( because i i i The following numbers can be taken at will ). n o w now now You can directly use the number array to maintain the prefix and ( Because of the former i − 1 i-1 i1 The two bit sequences are the same , So you can directly reduce that number 1). So the key problem is how to add repeatable permutation .

First, the repeatable arrangement should be in n ! n! n! Divided by the factorial of the number of occurrences of each element . That is, when we traverse to i i i When a , To be in ( n − i ) ! (n-i)! (ni)! Divided by c n t 1 ! × c n t 2 ! × c n t i ! . . . . × c n t n ! {cnt_1!\times cnt_2!\times cnt_i!....\times cnt_n!} cnt1!×cnt2!×cnti!....×cntn!
among c n t 1 cnt_1 cnt1 yes Before subtraction i − 1 i-1 i1 Digit number The number of corresponding numbers after . Then we can preprocess out i = 0 i=0 i=0 The above formula of tense is recorded as fenzi, from
1 c n t 1 ! × c n t 2 ! × ( c n t i − 1 ) ! . . . . × c n t n ! = 1 c n t 1 ! × c n t 2 ! × c n t i ! . . . . × c n t n ! × c n t i \frac{1}{cnt_1!\times cnt_2!\times (cnt_i-1)!....\times cnt_n!}=\frac{1}{cnt_1!\times cnt_2!\times cnt_i!....\times cnt_n!}\times cnt_i cnt1!×cnt2!×(cnti1)!....×cntn!1=cnt1!×cnt2!×cnti!....×cntn!1×cnti, After each iteration, you just need to fenzi *= cnt[t[i]] And update the cnt[t[i]] that will do .

ps. Don't forget to consider s s s It may happen to be t t t Prefix of , Began to forget , Fortunately, there are examples 1

Code

void solve() {
    
   cin >> n >> m;
   fac[0] = 1;
   for(int i = 1; i <= n; i++) {
    
   	fac[i] = (fac[i-1] * i) % P;
   }
   for(int i = 1; i <= n; i++) {
    
   	cin >> s[i];
   	update(s[i], 1);
   	cnt[s[i]]++;
   }
   for(int i = 1; i <= m; i++) {
    
   	cin >> t[i];
   }
   int ans = 0;
   int mi = min(n, m);
   int fz = 1;
   for(int i = 1; i <= 2e5; i++) {
    
   	if(cnt[i]) {
    
   		fz = fz * fac[cnt[i]] % P;
   	}
   }
   fz = power(fz, P - 2);
   int flag = 1;
   if(n >= m) {
    
   	flag = 0;
   }
   for(int i = 1; i <= mi; i++) {
    
   	int p = ask(t[i] - 1);
   	ans = (ans + p * fac[n-i] % P * fz % P) % P;
   	if(!cnt[t[i]]) {
    
   		flag = 0;
   		break;
   	}
   	fz = fz * cnt[t[i]] % P;
   	cnt[t[i]]--;
   	update(t[i], -1);
   }
   ans += flag;
   ans %= P;
   cout << ans << endl;
}
原网站

版权声明
本文为[Strezia]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207050443496029.html