Codeforces_805
A.当l == r时,肯定输出这个数就可以了,当存在两个或两个以上连续的数时,2肯定是最多的数,或最多的数之一。
#include<bits/stdc++.h> using namespace std; int l,r; int main() { ios::sync_with_stdio(false); cin >> l >> r; if(l == r) cout << l << endl; else cout << 2 << endl; return 0; }
B.aabb这个顺序一定不会有3位的回文串,并且不出现c。
#include<bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(false); cin >> n; int now = 0,cnt = 0; for(int i = 1;i <= n;i++) { if(now == 0) cout << "a"; else cout << "b"; cnt++; if(cnt == 2) { cnt = 0; now = 1-now; } } cout << endl; return 0; }
C.1->n->2->n-1...这样的顺序。
#include<bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(false); cin >> n; cout << (n-1)/2 << endl; return 0; }
D.我们发现,每次变换,会把a往后挪动,并且a后面的b翻倍,跑到a前面来。我们从字符串右往左找到每一个a,将其挪到所有b之后。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; string s; int main() { ios::sync_with_stdio(false); cin >> s; long long ans = 0,now = 0; for(int i = s.length()-1;i >= 0;i--) { if(s[i] == 'b') now = (now+1)%MOD; else { ans = (ans+now)%MOD; now = (now+now)%MOD; } } cout << ans << endl; return 0; }
E.刚开始题意看的一脸懵逼,以为T树是没有用的,但题目中有个条件,含有相同种类的点在树上是连通的,我们用这个特性dfs给G图染色即可,注意未出现的点也要染色。
#include<bits/stdc++.h> using namespace std; int n,m,cnt = 0,color[300005],a[300005]; vector<int> v[300005],s[300005]; void dfs(int now,int pre) { map<int,int> mp; for(int i = 0;i < s[now].size();i++) { int t = s[now][i]; if(color[t]) mp[color[t]] = 1; } int cntt = 0; for(int i = 0;i < s[now].size();i++) { int t = s[now][i]; if(color[t]) continue; while(mp.count(++cntt)); color[t] = cntt; } for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre) continue; dfs(t,now); } } int main() { ios::sync_with_stdio(false); cin >> n >> m; int ans = 1; for(int i = 1;i <= n;i++) { int x,y,now = 0; cin >> x; ans = max(x,ans); for(int j = 1;j <= x;j++) { cin >> y; s[i].push_back(y); } } for(int i = 1;i < n;i++) { int x,y; cin >> x >> y; v[x].push_back(y); v[y].push_back(x); } dfs(1,-1); cout << ans << endl; for(int i = 1;i <= m;i++) { if(color[i] == 0) cout << 1 << " "; else cout << color[i] << " "; } cout << endl; return 0; }
F.我们求出每个连通子图中每个点的到其他点的最长距离f,每个连通子图的直径d。
对于每一个询问,若两个点在同一个连通子图,则输出-1。
否则,我们考虑两个子图的任意两个点相连后的图的直径为max(fi + fj + 1, max(d1, d2))。
将每个联通子图中所有的d排序后,枚举第一个子图每个点,二分答案为max(d1, d2)的个数,之后就好处理了。
#include<bits/stdc++.h> using namespace std; int n,m,q,d[100005] = {0},dd[100005],D[100005],pre[100005]; vector<int> v[100005],vv[100005]; vector<long long> s[100005]; map<int,double> mp[100005]; int findd(int x) { return x == pre[x]?x:pre[x] = findd(pre[x]); } void join(int x,int y) { int xx = findd(x),yy = findd(y); if(xx != yy) pre[xx] = yy; } void dfs1(int now,int pre) { for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre) continue; dfs1(t,now); d[now] = max(d[now],d[t]+1); } } void dfs2(int now,int pre) { int max1 = -1,max2 = -1; dd[now] = d[now]; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(d[t] > max1) { max2 = max1; max1 = d[t]; } else max2 = max(max2,d[t]); } for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre) continue; int x = d[now],y = d[t]; if(d[t] == max1) d[now] = max2+1; else d[now] = max1+1; d[t] = max(d[t],d[now]+1); dfs2(t,now); d[now] = x; d[t] = y; } } int main() { ios::sync_with_stdio(false); cin >> n >> m >> q; for(int i = 1;i <= n;i++) pre[i] = i; while(m--) { int x,y; cin >> x >> y; v[x].push_back(y); v[y].push_back(x); join(x,y); } for(int i = 1;i <= n;i++) { if(findd(i) == i) { dfs1(i,-1); dfs2(i,-1); } } for(int i = 1;i <= n;i++) { D[findd(i)] = max(D[findd(i)],dd[i]); vv[findd(i)].push_back(dd[i]); } for(int i = 1;i <= n;i++) { if(vv[i].size() == 0) continue; sort(vv[i].begin(),vv[i].end()); s[i].resize(vv[i].size()); s[i][0] = vv[i][0]; for(int j = 1;j < s[i].size();j++) { s[i][j] = s[i][j-1]+vv[i][j]; } } while(q--) { int xx,yy; cin >> xx >> yy; int x = findd(xx),y = findd(yy); if(x == y) { cout << -1 << endl; continue; } if(vv[x].size() > vv[y].size() || vv[x].size() == vv[y].size() && x > y) swap(x,y); if(mp[x].count(y)) { cout << fixed << setprecision(9) << mp[x][y] << endl; continue; } double ans = 0; int maxx = max(D[x],D[y]); for(int i = 0;i < vv[x].size();i++) { int pos = upper_bound(vv[y].begin(),vv[y].end(),maxx-vv[x][i]-1)-vv[y].begin(); ans += (long long)pos*maxx; ans += (long long)(vv[y].size()-pos)*(vv[x][i]+1); ans += (long long)s[y][s[y].size()-1]; if(pos > 0) ans -= (long long)s[y][pos-1]; } ans = ans/vv[x].size()/vv[y].size(); mp[x][y] = ans; cout << fixed << setprecision(10) << ans << endl; } return 0; }