Greetings everyone! We hope you enjoyed the problems. Here is the editorial of the contest
H — Group Project
find the groups in which you and your crush are placed .
use ceil
function .
As You want that you and your crush will be in same group , find out Group number for both $$$G_a$$$ = ceil(a/x) (group number where you are placed) , $$$G_b$$$ = ceil(b/x) (group number where your crush is placed) . there are total of n diffrent value of x(group size) which is equiprobable. Hence Probability = P/Q . P = Number of group size's in which $$$G_a == G_b$$$ , Q = n .
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define ppb pop_back
#define MOD 998244353
const int N=1e5;
int binexp(int a, int b) {
int res = 1;
while (b > 0) {
if(b&1)
res = ((res%MOD)*(a%MOD))%MOD;
a = ((a%MOD)*(a%MOD))%MOD;
b >>= 1;
}
return res;
}
void solve(){
int n;
string a,b;
cin >> n >> a >> b;
int an = stoi(a.substr(7,3));
int bn = stoi(b.substr(7,3));
int ans = 0;
for(int i=1;i<=n;i++){
if((an-1)/i == (bn-1)/i){
ans++;
}
}
ans *= binexp(n,MOD-2);
ans %= MOD;
cout << ans << endl;
}
int32_t main()
{
auto begin = std::chrono::high_resolution_clock::now();
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifndef ONLINE_JUDGE
freopen("test0.in", "r", stdin);
freopen("test0.out", "w", stdout);
#endif
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}
E — Travelling Salesman Problem
Try doing something with the lowest common ancestor of $$$i$$$ and $$$i + 1$$$.
Prefix sums on tree?
Since we have to answer the problem offline, let's try to do something similar to difference arrays.
First root the tree on an arbitrary vertex — say $$$1$$$.
Say the lowest common ancestor of $$$i$$$ and $$$i + 1$$$ be $$$LCA$$$. We will add $$$1$$$ to $$$score[parent_i]$$$ and $$$score[i + 1]$$$, and subtract $$$1$$$ from $$$score[LCA]$$$ and $$$score[parent_{LCA}]$$$. A Now if we add up scores going from bottom to top, we will get the number of times each vertex is visited.
Each vertex in the path from $$$parent_i$$$ to $$$LCA$$$ and $$$i + 1$$$ to $$$LCA$$$ will get $$$+1$$$ to the score. Note that the $$$LCA$$$ is considered twice, so we have subtracted $$$1$$$ from $$$score[LCA]$$$. Also to prevent any addition to parents of $$$LCA$$$, we have subtracted $$$score[parent_{LCA}]$$$ as well.
#include<bits/stdc++.h>
using namespace std;
#define int long long
// LCA code source - usaco.guide
int depth[200010];
int up[200010][20];
int score[200010];
vector<int> adj[200010];
void dfs(int v) {
for(int i = 1; i < 20; i++) { up[v][i] = up[up[v][i - 1]][i - 1]; }
for (int x : adj[v]) {
if (x != up[v][0]) {
depth[x] = depth[up[x][0] = v] + 1;
dfs(x);
}
}
}
int jump(int x, int d) {
for(int i = 0; i < 20; i++) {
if ((d >> i) & 1) x = up[x][i];
}
return x;
}
int LCA(int a, int b) {
if (depth[a] < depth[b]) swap(a, b);
a = jump(a, depth[a] - depth[b]);
if (a == b) return a;
for(int i = 19; i >= 0; i--) {
int aT = up[a][i], bT = up[b][i];
if (aT != bT) a = aT, b = bT;
}
return up[a][0];
}
void clear(int n) {
for(int i = 0; i < n; i++) {
score[i] = 0;
depth[i] = 0;
adj[i].clear();
for(int j = 0; j < 20; j++)
up[i][j] = 0;
}
}
int32_t main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t; cin >> t;
while(t--) {
int n; cin >> n;
clear(n + 5);
for(int i = 0; i < n - 1; i++) {
int a, b; cin >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a);
}
dfs(1);
for(int i = 1; i < n; i++) {
int par = LCA(i, i + 1);
score[up[i][0]]++, score[i + 1]++;
score[par]--, score[up[par][0]]--;
}
vector<pair<int,int>> vp;
for(int i = 2; i <= n; i++) {
vp.push_back({-depth[i], i});
}
sort(vp.begin(), vp.end());
for(int i = 0; i < vp.size(); i++) {
score[up[vp[i].second][0]] += score[vp[i].second];
}
score[1]++; // initial stand
for(int i = 1; i <= n; i++) cout << score[i] << " ";
cout << "\n";
}
return 0;
}