Codeforces Round #819 (Div. 1 + Div. 2) and Grimoire of Code Annual Contest 2022 A-D
A. Mainak and Array
a有三种情况
一种是整个环都在转
另外两种是一个端点不转,其它点都在转
取个最值就可了
//#define int ll const int N = 2e5+10; int n,m; int a[N]; void solve() { // cin>>n>>m; cin>>n; int mx = 0; fo(i,1,n) cin>>a[i]; fo(i,1,n-1) { mx = max(mx,a[i] - a[i+1]); } mx = max(a[n] - a[1],mx); int t1 = a[1],t2 = a[n]; sort(a+1,a+1+n); cout<<max({t2 - a[1],a[n] - t1,mx})<<endl; }
B. Mainak and Interesting Sequence
分奇偶
而且如果m < n一定是no
m是奇数 n 是偶数也一定是no
两个都是偶数也是特殊情况
//#define int ll const int N = 1e5+10; int n,m; //13 / 2 //13 / 4//不行 //12 / 5//可以 //12 / 8//可以 //13 / 3//可以 void solve() { cin>>n>>m; if(m < n) { cout<<"No"<<endl;rt; } if(m % n == 0) { cout<<"Yes"<<endl; fo(i,1,n) { cout<<m / n<<' '; } cout<<endl; } else { if(m % 2 == 1 && n % 2 == 0) { cout<<"No"<<endl;rt; } else { cout<<"Yes"<<endl; if(m % 2 == 1) { int t = m / n; fo(i,1,n-1) { cout<<t<<' '; } cout<<m - t * (n -1)<<endl; } else { if(n % 2 == 1) { int t = m / n; fo(i,1,n-1) { cout<<t<<' '; } cout<<m - t * (n -1)<<endl; } else { int t = m / n; fo(i,1,n-2) { cout<<t<<' '; } cout<<(m - t * (n - 2)) / 2<< ' '<<(m - t * (n - 2)) / 2 <<endl; } } } } }
C. Jatayu's Balanced Bracket Sequence
AB是合法序列,(A)也是合法序列,但是(A)不能减少连通块的个数,AB,则A最左边的 ( 和B最右边的 ) 可以构成合法序列,连通块-1
一开始有n 个连通块,假如碰到 )( 连通块个数 -1
//#define int ll const int N = 1e5+10; int n,m; void solve() { // cin>>n>>m; cin>>n; int ans = n; string s;cin>>s; fo(i,1,2*n-1) { if(s[i] == '(' && s[i-1] == ')') { --ans; } } cout<<ans<<endl; }
D. Edge Split
最多n+2个边,也就是有三个环
假如没有环,将所有边染成红色和将一半的边染成红色结果是一样的
当一个图里增加一个环,连通块个数是不会变的,就会浪费一条边
考虑有环
将图拆了,生成一颗树。
剩下的边都是0
假如剩下三个点,也就是说它们两两有环
最方便的做法是保存这三个点的深度,以及这个点之前的点连到这个点的边
然后将一号点到三号点的边染成红色,并将三号点到之前的边染成蓝色,就不会出现环
const int N = 2e6+10,M = 2 * N; bool vis[N]; int n,m,ans[N]; int h[N],ne[M],w[M],e[M],idx; int pre[N],depth[N]; struct node { int a,b,id; }; V<node> extra; set<int>s; void add(int a,int b,int c) { e[idx] = b,ne[idx] = h[a],h[a] = idx ++ ,w[idx - 1] = c; } void dfs(int u) { vis[u] = 1; for(int i = h[u];~i;i=ne[i]) { int j = e[i]; if(!vis[j]) { pre[j] = w[i]; depth[j] = depth[u] + 1; dfs(j); ans[w[i]] = 1; } else if(depth[j] > depth[u]) { extra.pb({u,j,w[i]}); s.insert(j); s.insert(u); } } } void solve() { cin>>n>>m; s.clear(); extra.clear(); fo(i,0,n) { vis[i] = pre[i] = depth[i] = 0; h[i] = -1; } fo(i,0,m) ans[i] = 0; fo(i,1,m) { int u,v;cin>>u>>v; add(u,v,i); add(v,u,i); } dfs(1); if(extra.size() == 3 && s.size() == 3) { vector<int> a(s.begin(),s.end()); sort(a.begin(),a.end(),[&](int i,int j) { return depth[i] < depth[j]; }); for(auto it:extra) { int u = it.a,v = it.b,id = it.id; if(u == a[0] && v == a[2]) ans[id] = 1; } ans[pre[a[2]]] = 0; } fo(i,1,m) cout<<ans[i]; cout<<endl; }