Codeforces Round #411 (Div. 2) 题解

xiaoxiao2021-02-28  43

A:给定l和r,求[l,r]中的数的因数中出现次数最多的那一个 结论:如果l和r相同输出它 不然输出2

B:要求构造一个由abc组成的字符串 满足没有长度为3的回文子串的情况下c最少

发现只用ab构造出aabbaabbaabb….就能满足条件 c根本就用不到。

C:有n个点,从第i个点到第j个点的费用是(i+j) % (n+1) 求从任意点出发 到达所有点的最小费用

走法1->n->2->n-1->3->n-2…显然最优 输出(n-1)/2即可

D:给定一个由’a’和’b’组成的串 你要不断的把ab换成bba 直到没有ab 求换多少次,答案取模10^9+7

分析发现最后肯定变成bbb…bbbaaa…aaa的形式,所以不管怎么变步数应该是一样的。分析发现每个a能把他

后边的b变成2个b,而a要变的次数一定是后面b的个数,于是从后面开始处理,统计b的数量即可。

#include <bits/stdc++.h> using namespace std; const int maxn = 1e6+7; const int mod = 1e9+7; char s[maxn]; int main() { scanf("%s", s); int n=strlen(s); int cnt=0, ans = 0;; for(int i=n-1; i>=0; i--){ if(s[i]=='b'){ cnt++; } else{ ans += cnt; cnt *= 2; cnt %= mod; ans %= mod; } } cout<<ans%mod<<endl; }

E:

有一棵树,每个节点都有一些1-m的数字,个数和不超过5*10^5

要求你给1-m每个数字一个颜色 满足任意两个相同颜色的没有出现在同一个节点

保证1-m这些数字出现的位置构成原树的一个子图 n,m<=3*10^5

贪心DFS。因为这些数字都是连续的 所以假设一个数字在一个节点出现,却没在它的一个儿子节点出现,那么

它的那个儿子所在的子树一定没有它。

所以直接贪心即可 到达每一个节点的时候给这个节点上的数字中所有已经涂过的颜色打标记 然后给还没涂色

的涂尽量小的颜色。

#include <bits/stdc++.h> using namespace std; const int maxn = 3e5+7; set<int>s[maxn]; vector<int>G[maxn]; int n, m, cnt, ans[maxn]; void dfs(int x, int fa){ vector<int>v; if(fa==-1){ for(set<int>::iterator it = s[x].begin(); it != s[x].end(); it++){ ans[(*it)]=++cnt; } } else{ for(set<int>::iterator it = s[x].begin(); it != s[x].end(); it++){ if(ans[(*it)]){ v.push_back(ans[(*it)]); } } int sz=v.size(); sort(v.begin(),v.end()); int xx=0,yy=1; for(set<int>::iterator it = s[x].begin(); it != s[x].end(); it++){ if(ans[(*it)]==0){ while(xx<sz){ if(yy==v[xx]) xx++,yy++; else break; } ans[*it]=yy++; } cnt=max(cnt,yy-1); } } for(int i = 0; i < G[x].size(); i++){ int vv = G[x][i]; if(vv == fa) continue; if(vv!=fa){ dfs(vv, x); } } } int main() { scanf("%d%d", &n,&m); for(int i=1; i<=n; i++){ int x, y; scanf("%d", &x); while(x--){ scanf("%d", &y); s[i].insert(y); } } // for(int i=1; i<=n; i++){ // cout<<i<<":"; // for(auto &it:s[i]){ // cout<<it<<" "; // } // cout<<endl; // } for(int i=1; i<n; i++){ int u, v; scanf("%d%d", &u,&v); G[u].push_back(v), G[v].push_back(u); } memset(ans, 0, sizeof(ans)); cnt = 0; dfs(1, -1); cnt=max(cnt,1); printf("%d\n", cnt); for(int i=1; i<=m; i++) printf("%d ", ans[i]?ans[i]:1); }

F:不会搞

一堆结论题真心可怕。

转载请注明原文地址: https://www.6miu.com/read-85161.html

最新回复(0)