zoukankan      html  css  js  c++  java
  • 牛客【2021寒假集训营第一场】A-串

    【2021寒假集训营第一场】A-串

    dp,容斥原理,快速幂

    传送门

    这个题目就是容斥原理的应用,关键是弄明白长度为i的字符串根据us分为几种

    长度为i的字符串主要分为三种:

    • 不含u的
    • 含u不含us的
    • 含us的

    这三种加起来就是全集

    解法一:

    使用(f[i])表示长度为i的含有us的字符串

    可以分为以下两种:

    • 前i-1个字符串含有us,那么第i个字符可以是26个字母中任意一个:(f[i] += f[i-1]*26)
    • 前i-1个字符含有u,但是不含有us,那么第i个字符只需要填一个i即可:(f[i] += 26^{i-1} -25^{i-1} - f[i-1])
      • 前i-1个字符含有u(即全部组合减去不含有u的组合):(26^{i-1} -25^{i-1})
      • 不含有us,上面的结果减去含有us的即可,(26^{i-1} -25^{i-1}-f[i-1])

    所以结果就是(f[i] = 26^{i-1} -25^{i-1} + 25* f[i-1])

    注意这里计算幂的时候要使用到快速幂算法,其中还需要取模运算

    ac代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod = 1e9+7;
    int n;
    ll f[2000010];
    int q_pow(ll a, ll n)
    {
    	ll ans = 1;
        ll tot = a; // 这里必须是ll类型,不然就会出错!因为tot是指数上升的 
    	while(n){
    		if(n&1) ans = (ans*tot)%mod;
    		tot = (tot*tot)%mod;
    		n>>=1;
    	}
    	return ans%mod;
    }
    
    int main()
    {
    	cin >> n;
    	f[2] = 1;
    	for(int i=3; i<=n; ++i){
    		f[i] = (q_pow(26, i-1) - q_pow(25, i-1) + f[i-1]*25 % mod + mod)%mod; // 括号里面+mod是为了防止负数 
    	}
    	ll ans = 0;
    	for(int i=2; i<=n; ++i){
    		ans = (ans+f[i])%mod;
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    解法二:

    将一个长为i的字符串分为三类,并用(f[i][0/1/2])表示

    • (f[i][0])表示的是长度为i,不含有u的字符串
    • (f[i][1])表示的是长度为i,含有u,不含有us的字符串
    • (f[i][2])表示的是含有us的字符串

    则可以得到以下关系:

    1. (f[i][0] = 25*f[i-1][0]);即前i个不含有u的字符串为前i-1个不含u的字符串,末尾添加一个非u字符
    2. (f[i][1] = f[i-1][0] + f[i-1][1]*25);如1,根据公式理解即可
    3. (f[i][2] = f[i-1][1] + f[i-1][2]*26);如1,根据公式理解即可

    ac 代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod = 1e9+7;
    int n;
    ll f[1000010][3];
    int main()
    {
    	cin >> n;
    	f[2][0] = 25*25; 
    	f[2][1] = 50; 
    	f[2][2] = 1;
    	for(int i=3; i<=n; ++i){
    		f[i][0] = f[i-1][0]*25%mod;
    		f[i][1] = (f[i-1][0] + 25*f[i-1][1])%mod;
    		f[i][2] = (f[i-1][1] + 26*f[i-1][2])%mod;
    	} 
    	ll ans = 0;
    	for(int i=2; i<=n; ++i){
    		ans = (ans+f[i][2])%mod;
    	}
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    软件开发工具-4
    软件开发工具-3
    软件开发工具-2
    软件开发工具-1
    2020年06月02日_Node_exporter的docker部署方式监控网络不准确问题
    DELL OpenManage Server Administrator安装及使用
    yum下载rpm包和依赖包到指定目录(且不安装)
    诡异的docker网络问题解决
    nextcloud新实例安装时一直在登录页面转圈圈
    洛谷-P4414 [COCI2006-2007#2] ABC
  • 原文地址:https://www.cnblogs.com/VanHa0101/p/14406832.html
Copyright © 2011-2022 走看看