模拟赛#2 | 牛客普及周赛
题目链接:https://ac.nowcoder.com/acm/contest/59457#rank
AB 纯暴力
C
思维题
从任意情况入手, 设\(highbit(x)\)为数x的二进制表示最高位, 则容易发现当\(highbit(r)\)大于\(highbit(l)\)时, 总能异或出从\(highbit(r)\)到第一位每一位都为1的最优状况, 继续考虑当\(highbit(r) = highbit(l)\)时, 最后一位无论如何都不能有变化, 考虑下一位, 假如相同时情况类似, 继续考虑下一位... 容易猜想到需要找值不同的最高位来计算答案
(这题70分特别好拿, 两个特判加暴力就70了, 比赛的时候5分钟就拿了70分, 然后剩下30分想了一个小时)
代码
/*
Author: SJ
*/
#include<bits/stdc++.h>
const int N = 1e5 + 10;
using ll = long long;
using ull = unsigned long long;
ll t, l, r, ans;
int lowbit(ll x) {
return x & -x;
}
int find(ll x) {
int pos = 0;
while (x) {
pos++;
x >>= 1;
}
return pos;
}
int find2(ll x, ll y) {
int pos = 0, cnt = 0;
while (x && y) {
cnt++;
int tmp1 = (x & 1);
int tmp2 = (y & 1);
if (tmp1 != tmp2) {
pos = cnt;
}
x >>= 1;
y >>= 1;
}
return pos;
}
void solve() {
std::cin >> l >> r;
ans = 0;
if (l == r) {
std::cout << 0 << "\n";;
return;
}
int pos1 = find(l), pos2 = find(r);
if (pos2 > pos1) {
std::cout << (ll)std::pow(2, pos2) - 1 << "\n";
return;
}
int pos3 = find2(l, r);
std::cout << (ll)std::pow(2, pos3) - 1 << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> t;
while (t--) solve();
return 0;
}
D
归并排序 + 数学
先用归并排序\(O(nlogn)\)求出初始串逆序对的奇偶性, 然后根据"排列中任意两个数对换奇偶性改变"这一结论来\(O(1)\)回答即可
代码
/*
Author: SJ
*/
#include<bits/stdc++.h>
const int N = 1e5 + 10;
using ll = long long;
using ull = unsigned long long;
ll n, m, t[N], a[N], cnt, mark1;
void merge_sort(ll a[], int l, int r) {
if (l == r) return;
int mid = (l + r) / 2;
merge_sort(a, l, mid), merge_sort(a, mid + 1, r);
for (int i = l, j = l, k = mid + 1; i <= r; i++) {
if (j == mid + 1) {
t[i] = a[k++];
} else if (k == r + 1) {
cnt += k - mid - 1;
t[i] = a[j++];
} else if (a[j] <= a[k]) {
cnt += k - mid - 1;
t[i] = a[j++];
} else {
t[i] = a[k++];
}
}
for (int i = l; i <= r; i++) {
a[i] = t[i];
}
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n;
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
}
merge_sort(a, 1, n);
if (cnt % 2) mark1 = 1;
else mark1 = 0;
std::cin >> m;
for (int i = 1; i <= m; i++) {
int l, r;
std::cin >> l >> r;
if ((r - l + 1) % 2 == 0) {
int check1 = (r - l + 1) / 2;
mark1 = (check1 % 2) ? ((mark1 + 1) % 2) : mark1;
} else {
int check1 = (r - l) / 2;
mark1 = (check1 % 2) ? ((mark1 + 1) % 2) : mark1;
}
if (mark1 == 0) std::cout << "like" << "\n";
else std::cout << "dislike" << "\n";
}
return 0;
}
期望得分: 400/400

C这种题知道结论就一眼, 真是虚头巴脑

浙公网安备 33010602011771号