• AtCoder Beginner Contest 215


    C - One More aab aba baa

    求给定字符串的字典序第 (k) 小的排列。

    排列方式最多 (8!) 种,排序之后 (next\_permutation) 即可

    Sample Code (C++)
    int main()
    {
    	IOS; string s; int k; cin >> s >> k;
    	sort(s.begin(), s.end());
    	k --;
    	while(k -- ) next_permutation(s.begin(), s.end());
    	cout << s << endl;
    	return 0;
    } 
    

    D - Coprime 2

    给定一个序列 (A),求出 ([1, m]) 中所有符合条件的 (k)

    • (forall i, gcd(A_i, k) = 1)

    转化成 (k) 与所有 (A_i) 没有相同的因子。
    对所有 (A_i) 质因子分解,求出 (A) 序列的质因子集合, 再对每一个 (k) 质因子分解,若与 (A) 的质因子集合无交集,则合法。

    Sample Code (C++)
    map<int, int> mp;
    
    bool check(int x)
    {
    	for(int j = 2; j * j <= x; ++ j)
    		if(x % j == 0)
    		{
    			if(mp[j]) return 0;
    			while(x % j == 0) x /= j;
    		}
    	if(x > 1 && mp[x]) return 0;
    	return 1;
    }
    
    int main()
    {
    	IOS; int n, m; cin >> n >> m;
    	for(int i = 1; i <= n; ++ i)
    	{
    		int x; cin >> x;
    		for(int j = 2; j * j <= x; ++ j)
    			if(x % j == 0)
    			{
    				while(x % j == 0) x /= j;
    				mp[j] = 1; 
    			}
    		if(x > 1) mp[x] = 1;
    	}
    	vector<int> v;
    	v.push_back(1);
    	for(int i = 2; i <= m; ++ i)
    		if(check(i)) v.push_back(i);
    	cout << v.size() << endl;
    	for(auto x : v) cout << x << endl;
    	return 0;
    } 
    

    E - Chain Contestant

    给定一个由 (A - J) 组成的串,求从中选出子序列满足相同的字符必须相临的方案数。

    如果直接 (dp) , 无法得知前面是否已经出现过某种颜色。发现字符种类仅有 (10) 种,于是可以状态压缩记录某种颜色是否出现过。
    (dp[i][j][k]) 为从前 (i) 个字符中选择,颜色状态为 (j), 最后选择的颜色为 (k) 的合法方案数。
    初始状态为 (dp[i][1 << col_i][col_i] = 1)
    (dp[i][j][k] = dp[i - 1][j][k] + dp[i - 1][j - (1 << k)][t];;(选))
    (dp[i][j][k] = dp[i - 1][j][k];;(不选))
    答案即为 (sumlimits_{i = 0}^{1023}sumlimits_{j = 0}^9dp[n][i][j])。 复杂度 (O(2^{10} * n * 10))

    Sample Code (C++)
    int n;
    char str[N];
    LL dp[N][1 << M][M];
    
    int main()
    {
    	cin >> n >> (str + 1);
    	for(int i = 1; i <= n; ++ i)
    	{
    		int col = str[i] - 'A';
    		dp[i][1 << col][col] = 1;
    		for(int j = 0; j < (1 << 10); ++ j)
    		{
    			for(int k = 0; k < 10; ++ k)
    				if(j >> k & 1) 
    				{
    					dp[i][j][k] = (dp[i][j][k] + dp[i - 1][j][k]) % P;	
    					if(col == k) dp[i][j][k] = (dp[i][j][k] + dp[i - 1][j][k]) % P;
    				}
    			if(j >> col & 1)
    				for(int t = 0; t < 10; ++ t)	
    					if((j - (1 << col)) >> t & 1)
    						dp[i][j][col] = (dp[i][j][col] + dp[i - 1][j - (1 << col)][t]) % P;
    		}
    	}
    	LL res = 0;
    	for(int i = 0; i < (1 << 10); ++ i)
    		for(int j = 0; j < 10; ++ j)
    			res = (res + dp[n][i][j]) % P;
    	cout << res << endl;
    	return 0;
    } 
    

    F - Dist Max 2

    给一组点,定义两点之间的距离为 (min(|x_i - x_j|, |y_i - y_j|)), 求两个不同点的最大距离。

    最小值最大化问题,考虑二分答案。
    若一个答案 (k) 合法,则必须满足存在两个点使得 (|x_i - x_j| ge k), 并且 (|y_i - y_j| ge k), 于是可以考虑一个类似于滑动窗口的做法,将点按照 (x) 排序,对于当前点 (P) 来说,若队列中的点 (Q)(P)(x) 坐标差 (ge k) , 则 (Q) 可以加入答案集合,维护答案集合的最大值和最小值,判断当前点是否可以从答案集合中找出一个合法点,即 (y_{max} - y_p ge k)(y_p - y_{min} ge k)
    复杂度 (O(nlogn + nlogx_{max}))

    Sample Code (C++)
    vector<PII> v;
    
    bool check(int mid)
    {
    	queue<PII> q; int Max = 0, Min = INF;
    	for(auto p : v)
    	{
    		while(!q.empty() && p.fi - q.front().fi >= mid) 
    		{
    			Max = max(Max, q.front().se);
    			Min = min(Min, q.front().se);
    			q.pop();
    		}
    		if(Max - p.se >= mid || p.se - Min >= mid) return 1;
    		q.push(p);
    	}
    	return 0;
    }
    
    int main()
    {
    	IOS; int n; cin >> n;
    	for(int i = 0; i < n; ++ i) { int x, y; cin >> x >> y; v.push_back({x, y}); }
    	sort(v.begin(), v.end());
    	int l = 0, r = 1e9, res;
    	while(l <= r)
    	{
    		int mid = l + r >> 1;
    		if(check(mid)) { res = mid; l = mid + 1; }
    		else r = mid - 1;
    	}	
    	cout << res << endl;
    	return 0;
    } 
    

    G - Colorful Candies 2

    给定长度为 (n) 的序列,每个位置有一种颜色 (c_i), 对于每一个 (1 le k le n), 求随机选 (k) 个的期望不同颜色数。

    首先,考虑算贡献,将问题转化为某种颜色出现或者不出现,设 (X(i))(i) 这种颜色是否出现,出现为 (1), 不出现为 (0)
    假设共有 (m) 种颜色: (ans = E(sumlimits_{i = 1}^mX(i)) = sumlimits_{i = 1}^mE(X(i)))
    对于颜色 (i) , (E(X(i)) = 1 * P(X(i) = 1)), 假设颜色 (i)(n_i) 个,(E(X(i)) = dfrac{dbinom{n}{k} - dbinom{n - n_i}{k}}{dbinom{n}{k}})
    (ans = sumlimits_{i = 1}^mE(X(i)) = sumlimits_{i = 1}^mdfrac{dbinom{n}{k} - dbinom{n - n_i}{k}}{dbinom{n}{k}} = dfrac{sumlimits_{i = 1}^m(dbinom{n}{k} - dbinom{n - n_i}{k})}{dbinom{n}{k}})
    对于每一个 (k), 都要在 (O(m)) 的复杂度计算,整体复杂度 (O(n^2))
    发现对于每一个 (k) 来说,答案只和每个 (n_i) 有关,于是可以将 (n_i) 相同的颜色合并一下,同时计算,设合并后只有 (M) 种,第 (i) 种由 (a_i) 个数量为 (n_i) 的颜色组成
    (ans = dfrac{sumlimits_{i = 1}^m(dbinom{n}{k} - dbinom{n - n_i}{k})}{dbinom{n}{k}} = dfrac{sumlimits_{i = 1}^Ma_i(dbinom{n}{k} - dbinom{n - n_i}{k})}{dbinom{n}{k}})
    分析一下这样合并后的时间复杂度:(n_i > sqrt n) 的颜色, 不会超过 (sqrt n) 种, 否则总数大于 (n)(n_i le sqrt n) 的颜色,只有 (0) ~ (sqrt n) 这几种,总个数不超过 (2sqrt n), 故复杂度在 (O(n sqrt n))

    Sample Code (C++)
    int n;
    LL fac[N], ifac[N];
     
    LL power(LL a, LL b)
    {
    	LL res = 1;
    	for(; b; b >>= 1, a = a * a % P)
    		if(b & 1) res = res * a % P;
    	return res;
    } 
     
    void init()
    {
    	fac[0] = ifac[0] = 1;
     	for(int i = 1; i < N; i ++) fac[i] = fac[i - 1] * i % P;
    	ifac[N - 1] = power(fac[N - 1], P - 2);
    	for(int i = N - 2; i; -- i) ifac[i] = ifac[i + 1] * (i + 1) % P;
    }
     
    LL C(LL a, LL b)
    {
    	if(a < b) return 0;
    	return fac[a] * ifac[b] % P * ifac[a - b] % P;
    }
    
    int main()
    {
    	init(); IOS; cin >> n;
    	map<int, int> mp, v;
    	for(int i = 1; i <= n; ++ i) { int x; cin >> x; mp[x] ++; }
    	for(auto x : mp) v[x.se] ++;
    	for(int k = 1; k <= n; ++ k)
    	{
    		LL ans = 0;
    		for(auto x : v) ans = (ans + 1ll * x.se * (C(n, k) - C(n - x.fi, k) + P) % P) % P;
    		ans = ans * power(C(n, k), P - 2) % P;
    		cout << ans << endl;
    	}
    	return 0;
    } 
    
  • 相关阅读:
    [ 字典树题目 ]
    AC Challenge [ ACM-ICPC 2018 南京赛区网络预赛 ] [dfs + 二进制记忆化搜索 ]
    ACM-ICPC 2018 南京赛区网络预赛 J.Sum [ 类打表 ]
    Bzoj 3224.普通平衡树 [ 权值线段树 ]
    IP:网际协议
    网络概述
    HashSet
    idea中git各颜色文件含义
    keytool证书管理
    openssl证书管理
  • 原文地址:https://www.cnblogs.com/ooctober/p/15184288.html
Copyright © 2020-2023  润新知