首页 > 其他分享 >Codeforces 1906H Twin Friends

Codeforces 1906H Twin Friends

时间:2024-04-07 21:33:06浏览次数:17  
标签:cnt int Twin maxn fac invf 1906H binom Friends

考虑到 \(N\) 的字符组成其实是固定的。
所以可以把方案数拆为 \(A\) 的方案数 \(\times\) \(A, B\) 相匹配的方案数。

对于 \(A\) 的方案数,就是多重集组合数,为 \(\dfrac{n!}{\prod\limits_{i = 0}^{25} (cnt_{A, i}!)}\)。

接下来考虑求解 \(A, B\) 相匹配的方案数。
考虑到对于字符 \(c\),只能由 \(c, c + 1\) 来补。
那如果确定了 \(c + 1\) 的个数为 \(x\),就知道了还有 \(cnt_{A, c} - x\) 个需要用 \(c\) 来填。
那么剩下的又可以去选择部分填到 \(c - 1\)。

于是可以列出 \(\text{DP}\)。
设 \(f_{i, x}\) 为考虑了后 \(i\) 个字符,第 \(i + 1\) 填了 \(x\) 个字符给 \(i\) 的方案数。
那么令 \(s = cnt_{B, i} - (cnt_{A, i} - x)\),即填完 \(i\) 后 \(i\) 字符还剩的数量。
就有转移 \(f_{i - 1, y}\leftarrow f_{i, x}\times \binom{cnt_{A, i - 1}}{y}(0\le y\le \min\{s, cnt_{A, i - 1}\})\),指选 \(y\) 个填到 \(i - 1\),就有 \(\binom{cnt_{A, i - 1}}{y}\) 种选取方案。

发现转移到 \(f_{i, x}\) 一定乘了 \(\binom{cnt_{A, i}}{x}\),令 \(f_{i, x} = g_{i, x}\times\binom{cnt_{A, i}}{x}\)。
转移就变为了 \(g_{i - 1, y}\leftarrow f_{i, x}(0\le y\le \min\{s, cnt_{A, i - 1}\})\)。
那就可以差分优化 \(g\) 的转移了。

时间复杂度 \(O(n + m)\)。

代码
#include<bits/stdc++.h>
using ll = long long;
const ll mod = 998244353;
const int maxn = 2e5 + 10;
ll fac[maxn], inv[maxn], invf[maxn];
inline ll binom(int n, int m) {
   return fac[n] * invf[n - m] % mod * invf[m] % mod;
}
int cntA[26], cntB[26];
char S[maxn];
int f[26][maxn], g[26][maxn];
int main() {
   int n, m;
   scanf("%d%d", &n, &m);
   fac[0] = fac[1] = inv[0] = inv[1] = invf[0] = invf[1] = 1;
   for (int i = 2; i <= n; i++) {
      fac[i] = fac[i - 1] * i % mod;
      inv[i] = inv[mod % i] * (mod - mod / i) % mod;
      invf[i] = invf[i - 1] * inv[i] % mod;
   }
   scanf("%s", S + 1);
   for (int i = 1; i <= n; i++)
      cntA[S[i] - 'A']++;
   scanf("%s", S + 1);
   for (int i = 1; i <= m; i++)
      cntB[S[i] - 'A']++;
   g[25][0] = 1, g[25][1] = mod - 1;
   ll sum = 0;
   for (int i = 25; ~ i; i--) {
      for (int j = 1; j <= cntA[i]; j++)
         (g[i][j] += g[i][j - 1]) %= mod;
      for (int j = 0; j <= cntA[i]; j++)
         f[i][j] = g[i][j] * binom(cntA[i], j) % mod;
      for (int j = 0; j <= cntA[i]; j++)  {
         int s = cntB[i] - (cntA[i] - j);
         if (s < 0)
            continue;
         if (! i)
            (sum += f[i][j]) %= mod;
         else {
            s = std::min(s, cntA[i - 1]);
            (g[i - 1][0] += f[i][j]) %= mod, (g[i - 1][s + 1] += mod - f[i][j]) %= mod;
         }
      }
   }
   ll c = fac[n];
   for (int i = 0; i < 26; i++)
      (c *= invf[cntA[i]]) %= mod;
   printf("%lld\n", c * sum % mod);
   return 0;
}

标签:cnt,int,Twin,maxn,fac,invf,1906H,binom,Friends
From: https://www.cnblogs.com/rizynvu/p/18119975

相关文章

  • 电信aep—Ctwing平台使用笔记——mqttfx接入电信aep实现数据上传、命令下发。
    最近搞了电信平台,记录一下目录1.创建产品2.添加设备3.记录以下信息4.打开mqttfx​编辑5.试试​编辑6.建立属性7.建立服务8.打开mqttfx,输入主题与报文9.上传10指令下发1.创建产品2.添加设备3.记录以下信息4.打开mqttfx参数填写规则:1.BrokerAddress:从设......
  • CF763E Timofey and our friends animals
    使用回滚莫队可以有效降低思维含量。对于回滚莫队和可撤销并查集,本文不再赘述。假设当前询问是\([L,R]\),目前加入了\([l,r]\)的所有点和边。将\(r\)增加\(1\)时,连边\((r+1,v\in[l,r])\)。然后需要处理左边的散块。对于所有零散的\(l\),连边\((l,v\in[L,R])\)。上述两......
  • TwinCAT.Ads
     1、安装TC31-FULL-Setup.3.1.4024.35  倍福软件2、打开待调试的倍福项目      3、本机调试时如何查找Netid   4、创建上位机项目 引用动态链接库TwinCAT.Ads.dll  参考地址https://baijiahao.baidu.com/s?id=1669263124598569989&wfr=spider&for=pc......
  • CF516E Drazil and His Happy Friends 题解
    题目传送门记\(d=\gcd(n,m)\),发现只有编号在模\(d\)意义下相同的人之间会产生影响,那么有解当且仅当每个剩余系内有至少一个人是快乐的。所以在\(d>b+g\)时直接输出-1即可。对于剩下的情况,先令\(n\leftarrow\fracnd,m\leftarrow\fracmd\),如果\(n<m\)那么把男女交......
  • 初中英语优秀范文100篇-084Friends-朋友
    PDF格式公众号回复关键字:SHCZFW084记忆树1Whatarefriends?翻译什么是朋友简化记忆朋友句子结构主语这个句子没有明确的主语,因为它是一个疑问句,询问的是“朋友是什么”或“什么是朋友”。在疑问句中,疑问词(如“what”)通常作为主语的位置,但在语义上并不真正充当主语......
  • 大疆DJI Zenmuse L1点云导入contextcapture(iTwin capture)—轨迹文件Sbet转成符合conte
    大疆DJIZenmuseL1点云导入contextcapture(iTwincapture)—轨迹文件Sbet转成符合contextcapture要求的trajectoriesfile前言步骤1.在DJITerra中导出las格式的点云,然后找到轨迹文件sbet.txt2.将所有的sbet.txt转成需要的文件样式3.把点云导入contextcapture(iTwincapture)前言......
  • CF763E Timofey and our friends animals题解
    题目链接:CF或者洛谷简单来说就是求\([l,r]\)这些点都存在的情况下,连通块的数量,看到七秒时限,而且每个点相连的边数很少,可以想到离线下来使用莫队类的算法解决连通块问题,一般可以考虑使用并查集解决。对于并查集来说,它的增加是非常简单的,但删除是困难的,可持久化并查集时空常数......
  • Delphi 类(TObject、TPersistent、TComponent、TControl、TWinControl、TCustomControl
     TObject:    VCL中所有类的根类,即是说:VCL中所有的类/组件/控件都是从TObject中继承而来。TObject类中定义了基本的构造方法和析构方法。  TPersistent:    继承于TObject,按字典中的意思是“持久类”(姑且这样叫它吧,因为我一直就是这样叫这个类的-_-|)。该类在VCL中......
  • CF1835C Twin Clusters 题解
    题目链接点击打开链接题目解法很牛逼的构造题好像随也可以过长度为\(2^{k+1}\)的序列的不同区间有\(2^{2k+1}\)个,值域是\(4^k\),所以一定有解将\(a\)做一遍前缀和,那么问题转化成了找\(s_{r1}\opluss_{l1-1}=s_{r2}\opluss_{l2-1}\)先讲一讲具体做法:按照前\(k\)......
  • TwinkleTray:优雅地管理多显示器的亮度
    官网:https://twinkletray.com这个程序的最大特点就是UI界面做得很像Windows原生应用,有win10和win11两种风格的外观可选因为设置界面是支持中文的,所以这里就不对各个功能进行讲解,只介绍一些简单的特性显示器设置支持为每个显示器命名,排序可以隐藏某个显示器,或者隐藏不活动的......