Codeforces Round 1023 (Div. 2)
A. LRC and VIP
将数组分为不为空的两组,要求每组gcd不同。
首先考虑不能分组的情况:整个数组只有一个数。
其他情况均成立,所以将最大值单独分为一组即可。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 500010 , M = 6000000 , mod = 998244353 ;
int n ;
int a[110] ;void solve()
{cin >> n ;int mx = 0 ;set<int> st ;for(int i = 1 ; i <= n ; i ++) {cin >> a[i] ;mx = max(a[i] , mx) ;st.insert(a[i]) ;}if(st.size() == 1) {cout << "No" << "\n" ;return ;}cout << "Yes" << "\n" ;for(int i = 1 ; i <= n ; i ++)if(a[i] != mx) cout << "1" << " " ;else cout << "2" << " " ;cout << "\n" ;
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;cin >> t ;while (t --) solve() ;return 0;
}
B. Apples in Boxes
如果一开始不管tom怎么拿,max-min>k,那么tom输,否则,就一定可以拿完所有的苹果,统计数量即可。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 500010 , M = 6000000 , mod = 998244353 ;
int n , k ;
int a[N] ;void solve()
{cin >> n >> k ;int sum = 0 ;for(int i = 1 ; i <= n ; i ++) cin >> a[i] , sum += a[i] ;sort(a + 1 , a + n + 1) ;if(max(a[n] - 1 , a[n - 1]) - a[1] > k) {cout << "Jerry\n" ;return ;}if(sum % 2) cout << "Tom\n" ;else cout << "Jerry\n" ;
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;cin >> t ;while (t --) solve() ;return 0;
}
C. Maximum Subarray Sum
首先我们先统计s中是否有0,如果没有只要最大子段和不为k则输出"No"。
如果有0,则我们先把所有对应位置填上-1e15,如果这个时候最大子段和大于k,则输出"No"。
如果不满足以上两种情况则说明有答案。我们只需要改变s中第一个0位置的数,这时可以用二分的方法填充该位置。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 200010 , M = 6000000 , mod = 998244353 ;
int n , k ;
int a[N] , f[N] ;
string s ;
int check(int p) {int mx = -1e18 ;for(int i = 1 ; i <= p ; i ++) {f[i] = max(f[i - 1] + a[i] , a[i]) ;mx = max(mx , f[i]) ;}return mx ;
}
void solve()
{cin >> n >> k >> s ;s = " " + s ;for(int i = 1 ; i <= n ; i ++) {cin >> a[i] ;}int f = 0 ;for(int i = 1 ; i <= n ; i ++)if(s[i] == '0') {f = i ;break ;}int mx = check(n) ;if(!f && mx != k) {cout << "No\n" ;return ;}if(mx == k) {cout << "Yes\n" ;for(int i = 1 ; i <= n ; i ++)cout << a[i] << " " ;cout << "\n" ;return ;}for(int i = 1 ; i <= n ; i ++)if(s[i] == '0') a[i] = -1e15 ;if(check(n) > k) {cout << "No\n" ;return ;}cout << "Yes" << "\n" ;int p = f ;for(int i = f + 1 ; i <= n ; i ++)if(s[i] == '1') p = i ;else break ;int l = -1e15 , r = 1e15 ;while(l < r) {int mid = (l + r - 1) / 2 ;a[f] = mid ;if(check(p) >= k) r = mid ;else l = mid + 1 ;}a[f] = l ;for(int i = 1 ; i <= n ; i ++) cout << a[i] << " " ;cout << "\n" ;
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;cin >> t ;while (t --) solve() ;return 0;
}
D. Apple Tree Traversing
维护树的最长直径,注意不要重复搜索,时间复杂度为。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 200010 , M = N * 2 , mod = 998244353 ;
int n ;
int h[N] , e[M] , ne[M] , idx ;
int d[N] , st[N] , fa[N] ;
struct node{int d , u , v ;
};
vector<node> res ;bool cmp(node a , node b) {if(a.d != b.d) return a.d > b.d ;if(a.u != b.u) return a.u > b.u ;return a.v > b.v ;
}
void add(int a , int b) {e[idx] = b , ne[idx] = h[a] , h[a] = idx ++ ;
}
void dfs(int u , vector<int> &q) {q.push_back(u) ;for(int i = h[u] ; ~i ; i = ne[i]) {int j = e[i] ;if(st[j] || fa[u] == j) continue;fa[j] = u ;d[j] = d[u] + 1 ;dfs(j , q) ;}
}
void dfs1(int root) {vector<int> q ;d[root] = 0 , fa[root] = -1 ;dfs(root , q) ;for(int i = 0 ; i < q.size() ; i ++) {if(d[q[i]] > d[root] || (d[q[i]] == d[root] && q[i] > root))root = q[i] ;}q.clear() ;d[root] = 0 , fa[root] = -1 ;dfs(root , q) ;int u = root ;for(int i = 0 ; i < q.size() ; i ++) {if(d[q[i]] > d[u] || (d[q[i]] == d[u] && q[i] > u))u = q[i] ;}res.push_back({d[u] + 1 , max(u , root) , min(u , root)}) ;for(int i = u ; u != -1 ; u = fa[u])st[u] = 1 ;for(int i = 0 ; i < q.size() ; i ++) {if(!st[q[i]])dfs1(q[i]) ;}
}
void solve()
{cin >> n ;res.clear() ;for(int i = 0 ; i <= n ; i ++) h[i] = -1 , d[i] = 0 , st[i] = 0 , fa[i] = -1 ;for(int i = 0 ; i < n - 1 ; i ++) {int u , v ;cin >> u >> v ;add(u , v) , add(v , u) ;}dfs1(1) ;sort(res.begin() , res.end() , cmp) ;for(int i = 0 ; i < res.size() ; i ++)cout << res[i].d << " " << res[i].u << " " << res[i].v << " " ;cout << "\n" ;
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;cin >> t ;while (t --) solve() ;return 0;
}