当前位置:网站首页>#775 Div.1 C. Tyler and Strings 组合数学
#775 Div.1 C. Tyler and Strings 组合数学
2022-07-05 04:43:00 【Strezia】
C
组合数学,1900,数状数组
题意
给出 s , t s, t s,t 两个序列,长度分别为 n , m n,m n,m,问 s s s 有多少种排序方式满足 s s s 的字典序比 t t t 小。 1 ≤ n , m ≤ 2 e 5 1\leq n,m\leq 2e5 1≤n,m≤2e5
思路
因为是按字典序比较,所以如果 s 1 < t 1 s_1<t_1 s1<t1 之后的就可以随便排了,所以考虑枚举前 i − 1 i-1 i−1 位相同且 s i < t i s_i<t_i si<ti 的排序方式有 c n t i cnt_i cnti 种,最后的答案就是 ∑ i = 1 i = n c n t i \sum_{i=1}^{i=n} cnt_i ∑i=1i=ncnti 。
那么如何求 c n t i cnt_i cnti 呢?如果不考虑可重复排列,那么 c n t i = n o w × ( n − i ) ! cnt_i= now \times (n-i)! cnti=now×(n−i)! ,即到第 i 位当前满足小于 t i t_i ti 的个数乘上之后数的全排列(因为 i i i 后面的数可以随便取了)。 n o w now now 可以直接用数状数组维护前缀和(因为前 i − 1 i-1 i−1 位两序列相同,所以可以直接将那个数字数量减1)。于是问题重点在于加上可重复排列后怎么做。
首先可重复排列要在 n ! n! n! 的基础上除以每个元素出现数量的阶乘。即当我们遍历到第 i i i 位时,要在 ( n − i ) ! (n-i)! (n−i)! 的基础上除以 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!
其中 c n t 1 cnt_1 cnt1 是减去前 i − 1 i-1 i−1 位数字后的对应数字的数量。然后我们就可以先预处理出 i = 0 i=0 i=0 时的上式记为 fenzi
,由
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!×(cnti−1)!....×cntn!1=cnt1!×cnt2!×cnti!....×cntn!1×cnti,只需每次遍历后将 fenzi *= cnt[t[i]]
并更新 cnt[t[i]]
即可。
ps.不要忘记考虑 s s s 可能恰好为 t t t 的前缀的情况,开始忘了,还好有样例1
代码
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;
}
边栏推荐
- Function (error prone)
- Raki's notes on reading paper: soft gazetteers for low resource named entity recognition
- Special information | finance, accounting, audit - 22.1.23
- Basic analysis of IIC SPI protocol
- 【科普】热设计基础知识:5G光器件之散热分析
- Error statuslogger log4j2 could not find a logging implementation
- 2021 electrician cup (the 12th "China Society of electrical engineering Cup" National Undergraduate electrician mathematical modeling) detailed ideas + codes + references
- 2022-2028 global and Chinese virtual data storage Market Research Report
- level17
- Private collection project practice sharing [Yugong series] February 2022 U3D full stack class 006 unity toolbar
猜你喜欢
直播预告 | 容器服务 ACK 弹性预测最佳实践
函數(易錯)
OWASP top 10 vulnerability Guide (2021)
Fonction (sujette aux erreurs)
The principle of attention mechanism and its application in seq2seq (bahadanau attention)
Thematic information | carbon, carbon neutrality, low carbon, carbon emissions - 22.1.9
防护电路中的元器件
10 programming habits that web developers should develop
[Business Research Report] Research Report on male consumption trends in other economic times -- with download link
The 22nd Spring Festival Gala, an immersive stage for the yuan universe to shine into reality
随机推荐
取余操作是一个哈希函数
[groovy] closure (Introduction to closure class closure | this, owner, delegate member assignment and source code analysis)
Decryption function calculates "task state and lifecycle management" of asynchronous task capability
Is $20billion a little less? Cisco is interested in Splunk?
Neural networks and deep learning Chapter 5: convolutional neural networks reading questions
Burpsuite grabs app packets
Practice | mobile end practice
托管式服务网络:云原生时代的应用体系架构进化
Aperçu en direct | Services de conteneurs ACK flexible Prediction Best Practices
C26451: arithmetic overflow: use the operator * on a 4-byte value, and then convert the result to an 8-byte value. To avoid overflow, cast the value to wide type before calling the operator * (io.2)
49 pictures and 26 questions explain in detail what is WiFi?
Private collection project practice sharing [Yugong series] February 2022 U3D full stack class 006 unity toolbar
[crampon programming] lintcode decoding Encyclopedia - 872 termination process
[goweb development] Introduction to authentication modes based on cookies, sessions and JWT tokens
[crampon programming] lintcode decoding Encyclopedia - 1100 strange printer
Leetcode 222 number of nodes of complete binary tree
[illusory engine UE] method to realize close-range rotation of operating objects under fuzzy background and pit recording
The principle of attention mechanism and its application in seq2seq (bahadanau attention)
MySQL in-depth learning - index creation and deletion, index design principles, index failure scenarios, query optimization, index push down ICP
Invalid bound statement (not found) in idea -- problem solving