Given an integer \( n \), construct a permutation of \( 1 \) to \( n \) such that for every interval \([l, r]\), the bitwise OR of elements in the interval is at least the length of the interval. The problem contains multiple test cases.
The solution is straightforward: the identity permutation \( (1, 2, \ldots, n) \) satisfies the condition. This is because for any interval \([l, r]\), the bitwise OR will include all numbers from \( l \) to \( r \), ensuring the result is at least \( r-l+1 \).
#include <iostream>
#include <vector>
using namespace std;
int main() {
int test_cases;
cin >> test_cases;
while (test_cases--) {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cout << i << " ";
}
cout << endl;
}
return 0;
}
</vector></iostream>
Problem B: Fix You
Given a grid of characters 'C', 'D', and 'R', modify the minimum number of cells such that every path from the top-left corner (1,1) to the bottom-right corner (n,m) contains exactly one 'C' character.
The optimal solution requires making all cells in the last column 'D' and all cells in the last row 'R'. This ensures that any valid path must include exactly one 'C' from the rest of the grid.
#include <iostream>
#include <vector>
using namespace std;
const int MAX = 100;
void solve() {
int rows, cols;
cin >> rows >> cols;
vector<string> grid(rows);
for (int i = 0; i < rows; i++) {
cin >> grid[i];
}
int modifications = 0;
for (int i = 0; i < rows; i++) {
if (grid[i][cols-1] != 'D' && grid[i][cols-1] != 'C') {
modifications++;
}
}
for (int j = 0; j < cols; j++) {
if (grid[rows-1][j] != 'R' && grid[rows-1][j] != 'C') {
modifications++;
}
}
cout << modifications << endl;
}
int main() {
int test_cases;
cin >> test_cases;
while (test_cases--) {
solve();
}
return 0;
}
</string></vector></iostream>
Problem C: Cyclic Permutations
Count the number of permutations of length \( n \) that do not contain any cyclic permutations of length 3. A permutation is cyclic if it contains a subsequence with the same relative ordering as (2,1,3) or (3,1,2).
The solution is based on the observation that acyclic permutations are exactly the single-peaked permutations. The number of single-peaked permutations is \( 2^{n-1} \), so the answer is \( n! - 2^{n-1} \).
#include <iostream>
using namespace std;
const int MOD = 1000000007;
int main() {
int n;
cin >> n;
// Calculate n! mod MOD
long long factorial = 1;
for (int i = 1; i <= n; i++) {
factorial = (factorial * i) % MOD;
}
// Calculate 2^(n-1) mod MOD
long long power = 1;
for (int i = 1; i < n; i++) {
power = (power * 2) % MOD;
}
// Compute result
long long result = (factorial - power + MOD) % MOD;
cout << result << endl;
return 0;
}
</iostream>
Problem D: 505
Given an \( n \times m \) binary matrix, determine the minimum number of cell changes required sothat every even-sized square submatrix contains an odd number of 1s. Report if it's impossible.
If both dimensions are at least 4, it's impossible. Otherwise, we handle cases based on the smaller dimension:
- For 1×m matrices: no changes needed.
- For 2×m matrices: there are two possible patterns for column parities.
- For 3×m matrices: there are four possible patterns for adjacent row pairs.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX = 1000000;
void solve() {
int rows, cols;
cin >> rows >> cols;
vector<string> grid(rows);
for (int i = 0; i < rows; i++) {
cin >> grid[i];
}
// If both dimensions are >= 4, it's impossible
if (rows >= 4 && cols >= 4) {
cout << -1 << endl;
return;
}
// Transpose if necessary to ensure rows <= 3
if (rows > cols) {
vector<string> transposed(cols, string(rows, ' '));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
transposed[j][i] = grid[i][j];
}
}
grid = transposed;
swap(rows, cols);
}
if (rows == 1) {
cout << 0 << endl;
} else if (rows == 2) {
int option1 = 0, option2 = 0;
for (int j = 0; j < cols; j++) {
if ((grid[0][j] - '0') ^ (grid[1][j] - '0') != (j & 1)) {
option1++;
} else {
option2++;
}
}
cout << min(option1, option2) << endl;
} else { // rows == 3
int option1 = 0, option2 = 0, option3 = 0, option4 = 0;
for (int j = 0; j < cols; j++) {
bool top = (grid[0][j] - '0') ^ (grid[1][j] - '0') != (j & 1);
bool bottom = (grid[1][j] - '0') ^ (grid[2][j] - '0') != (j & 1);
if (top || bottom) option1++;
if (!top || bottom) option2++;
if (top || !bottom) option3++;
if (!top || !bottom) option4++;
}
cout << min({option1, option2, option3, option4}) << endl;
}
}
int main() {
int test_cases;
cin >> test_cases;
while (test_cases--) {
solve();
}
return 0;
}
</string></string></algorithm></vector></iostream>
Problem E: Pairs of Pairs
Given a connected undirected graph, either find a simple path of length at least \( \lceil n/2 \rceil \), or pair at least \( \lceil n/2 \rceil \) nodes (in even number) such that no two pairs form a complete subgraph on 4 nodes.
The solution uses DFS trees. If any node has depth at least \( \lceil n/2 \rceil \), we can output the path from that node to the root. Otherwise, we can pair nodes at the same depth level in the DFS tree, as the tree property ensures no edges between different pairs.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX = 500000;
vector<int> graph[MAX + 1];
bool visited[MAX + 1];
int parent[MAX + 1], depth[MAX + 1];
vector<int> nodes_by_depth[MAX + 1];
void dfs(int node = 1) {
visited[node] = true;
for (int neighbor : graph[node]) {
if (!visited[neighbor]) {
parent[neighbor] = node;
depth[neighbor] = depth[node] + 1;
dfs(neighbor);
}
}
}
void solve() {
int n, m;
cin >> n >> m;
// Clear graph and data structures
for (int i = 1; i <= n; i++) {
graph[i].clear();
nodes_by_depth[i].clear();
visited[i] = false;
parent[i] = 0;
depth[i] = 0;
}
// Read edges
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
// Build DFS tree
depth[1] = 1;
dfs();
// Check for long path
for (int i = 1; i <= n; i++) {
if (depth[i] >= (n + 1) / 2) {
cout << "PATH\n";
cout << depth[i] << "\n";
int node = i;
while (node != 0) {
cout << node << " ";
node = parent[node];
}
cout << "\n";
return;
}
nodes_by_depth[depth[i]].push_back(i);
}
// Otherwise, pair nodes at same depth
cout << "PAIRING\n";
int pairs = 0;
for (int i = 1; i <= n; i++) {
pairs += nodes_by_depth[i].size() / 2;
}
cout << pairs << "\n";
for (int i = 1; i <= n; i++) {
for (int j = 0; j + 1 < nodes_by_depth[i].size(); j += 2) {
cout << nodes_by_depth[i][j] << " " << nodes_by_depth[i][j + 1] << "\n";
}
}
}
int main() {
int test_cases;
cin >> test_cases;
while (test_cases--) {
solve();
}
return 0;
}
</int></int></algorithm></vector></iostream>