首页 > 其他分享 >Hetao BS0036 负负得正 题解 [ 黄 ] [ 组合数学 ]

Hetao BS0036 负负得正 题解 [ 黄 ] [ 组合数学 ]

时间:2024-06-16 20:33:42浏览次数:29  
标签:int 题解 字母 texttt 枚举 long Hetao 负负得正 mod

很简单的板子题,本来想放个思维难度高一点的黄,结果这把是板子局

部分分:

第一个部分分就是暴力枚举。
第二个部分分对 \(\texttt{b}\) 的位置进行枚举,然后做一下前缀和,统计一下。
第三个部分分就接近正解了,是留给会正解但不会快速幂求组合数的。
第四个部分分是给没有优化枚举 \(\texttt{c}\) 的位置的大常数做法。

正解:

显然,我们对于这种三段式子序列,通常都会根据中间那一段计算,本题恰好是中间有 \(1\) 个字母。

因此,我们可以枚举 \(\texttt{b}\) 的位置,对于 \(\texttt{a}\) 的值,我们选一个和 \(\texttt{b}\) 的值不同的字母,并记前面有 \(x\) 个这样的字母,计算 \(C(x,n)\) 即为 \(\texttt{a}\) 的取法。这里要对所有字母的数量进行前缀和,记为 \(f\) 。

然后对于 \(\texttt{c}\) 的取法,我们对字母的数量进行后缀和,记为 \(h\) 。那么既然前面两个字母已经被占用了,那么 \(\texttt{c}\) 就只能取剩下 \(24\) 个字母,于是将后面总字母数减去 \(h[ \texttt{a} ]\) 与 \(h[ \texttt{b} ]\) ,就是 \(\texttt{c}\) 的取法。这样就省掉了枚举 \(\texttt{c}\) 的一重循环。

然后每一位算一下贡献即可。

注意要用快速幂算组合数,如果用递推会 MLE 。

时间为 \(O(26m)\) 。

代码:

#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int f[1000005],g[1000005],l[1000005][30],r[1000005][30],n;
long long ans=0;
string s;
long long qpow(long long a,long long b)
{
	long long res=1;
	while(b)
	{
		if(b&1)res=res*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return res%mod;
}
void init()
{
	f[0]=g[0]=1;
	for(int i=1;i<=1000000;i++)
	{
		f[i]=1ll*f[i-1]*i%mod;
		g[i]=1ll*g[i-1]*qpow(i,mod-2)%mod;
	}
}
long long getc(long long n,long long m)
{
	return 1ll*f[n]*g[n-m]%mod*g[m]%mod;
}
int main()
{
    freopen("prove.in","r",stdin);
    freopen("prove.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	init();
	cin>>n;
	cin>>s;
	for(int i=1;i<s.length();i++)
	{
		for(int j=0;j<26;j++)
		{
			l[i][j]=l[i-1][j];
		}
		l[i][s[i-1]-'a']++;
	}
	for(int i=s.length()-2;i>=0;i--)
	{
		for(int j=0;j<26;j++)
		{
			r[i][j]=r[i+1][j];
		}
		r[i][s[i+1]-'a']++;
	}
	char a,b;
	for(int i=1;i<s.length()-1;i++)
	{
		b=s[i];
		for(int j=0;j<26;j++)
		{
			a=j+'a';
			if(a!=b&&l[i][j]>=n)ans+=1ll*getc(l[i][j],n)%mod*(1ll*(s.length()-i-1-r[i][j]-r[i][b-'a']))%mod;
			ans%=mod;
		}
	}
	cout<<ans%mod;
	return 0;
}

标签:int,题解,字母,texttt,枚举,long,Hetao,负负得正,mod
From: https://www.cnblogs.com/zhr0102/p/18251201

相关文章

  • 题解 | #查找薪水记录超过15条的员工号以及其记录次数t#
    高德Java后端一面(秒挂)百度算法岗面经上海网易互娱游戏策划sp一二三面面经(已OC)网易互娱/阿里互娱游戏策划一面面经【网易互娱】游戏设计师校招实习面试(已OC)[已oc]网易互娱游戏设计师(系统关卡数值)面经[已oc]网易互娱游戏设计师(系统关卡数值)面经网易互娱游戏设计师(系统......
  • C++题解—1140—亲密数对(东方博宜OJ)
    题目描述:键盘输入 N,N 在2至 2000之间,求 2 至 N 中的亲密数对,就是A的因子和等于B,B的因子和等于A ,且A≠B。如 48和 75是亲密数对。48的因子和为2+3+4+6+8+12+16+24=75 ,而 75的因子和3+5+15+25=48 。输入:只有一行,为一个整数 N( 2≤N≤2000 )。输出:输出......
  • [题解]ABC358E Alphabet Tiles
    AtCoder~E-AlphabetTilesLuogu~ABC358EAlphabetTiles题意简述给定正整数\(K\)和\(C_1,C_2,\dots,C_{26}\)。请求出长度在\(1\)到\(K\)之间,满足下列条件的字符串个数(取模\(998244353\)):该字符串全由大写字母组成。对于\(1\lei\le26\),下面条件成立:设\(a......
  • 不同PC设备共用同用一套键鼠,以及使用Barrier常见问题解决方案
    设备环境:一台windows11,一台ubuntu桌面版网络环境:使用同一wifi一、下载安装windows安装下载地址:Releasev2.4.0·debauchee/barrier·GitHububuntu安装sudoapt-getinstallbarrier二、设置使用服务端设置服务端作为主控端,键鼠连接的是服务端设备,配置连接......
  • 【秋招突围】2024届秋招笔试-小红书笔试题-第一套-三语言题解(Java/Cpp/Python)
    ......
  • WebGoC题解(4) 115.第5题 同心圆(比赛模拟题)
    题目描述学校准备在颁奖会把这次比赛的前10名的成绩用崭新的形状表示出来,这个艰巨的任务交给了小C。为了和以往不同,小C决定用每个学生的成绩作为半径画同心圆来表示。这个创新的举动需要你使用GoC编程,在一个黑色实心圆背景下,用10个红色圆表示成绩。具体形状参见输入输出样例......
  • 谢启鸿第四版高等代数第七章习题解析
    前言:之前写过两篇第七章习题解析,本篇主要是补充,将之前没有来得及写上的习题补充完整,顺便归个类。前两篇看主页吧,不指路了。习题7.4部分1(1).根据下列不变因子组写出有理标准型:解:排除0次多项式,的友阵为(1),的展开式为,则其友阵为可以得到有理标准型为.2(1).求下列矩阵的......
  • Codeforces Round 836题解(A、B、C)
    A.SSeeeeiinnggDDoouubbllee直接将原字符串翻转一下拼到原字符串的后面就构成了回文串。strings;voidsolve(){cin>>s;cout<<s;reverse(s.begin(),s.end());cout<<s<<'\n';}B.XOR=Average分\(n\)的奇偶性考虑,若\(n\)为奇数,我们可以......
  • Codeforces Round 952 (Div. 4) 题解分享
    A.CreatingWords思路模拟,交换输出即可codeinlinevoidsolve(){stringa,b;cin>>a>>b;swap(a[0],b[0]);cout<<a<<''<<b<<endl; return;}B.MaximumMultipleSum思路暴力枚举数学不会()codein......
  • 【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【贪心/脑筋急转弯】2
    有LeetCode算法/华为OD考试扣扣交流群可加948025485可上全网独家的欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明示例三......