文章目录
- [[A - 小苯的石子游戏](https://ac.nowcoder.com/acm/contest/73854/A)](#A - 小苯的石子游戏)
- [[B - 小苯的排序疑惑](https://ac.nowcoder.com/acm/contest/73854/B)](#B - 小苯的排序疑惑)
- [[C - 小苯的IDE括号问题(easy)](https://ac.nowcoder.com/acm/contest/73854/C)](#C - 小苯的IDE括号问题(easy))
- [[D - 小苯的IDE括号问题(hard)](https://ac.nowcoder.com/acm/contest/73854/D)](#D - 小苯的IDE括号问题(hard))
- [[E - 小苯的数组构造](https://ac.nowcoder.com/acm/contest/73854/E)](#E - 小苯的数组构造)
- [[F - 小苯的数组切分](https://ac.nowcoder.com/acm/contest/73854/F)](#F - 小苯的数组切分)
- [[G - 小苯的逆序对](https://ac.nowcoder.com/acm/contest/73854/G)](#G - 小苯的逆序对)
A - 小苯的石子游戏
cpp
string solve() {
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i];
int A = 0, B = 0, mode = 0;
for (int i = n - 1; i >= 0; i --, mode ^= 1)
if (mode & 1) B += a[i];
else A += a[i];
return A > B ? "Alice" : "Bob";
}
B - 小苯的排序疑惑
cpp
string solve() {
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i], b[i] = a[i];
sort(a, a + n);
return a[0] == b[0] || a[n - 1] == b[n - 1] ? yes : no;
}
C - 小苯的IDE括号问题(easy)
双指针
cpp
void solve() {
cin >> n >> m >> s;
int l = s.find('I') - 1, r = l + 2;
while (m --) {
string op; cin >> op;
if (op[0] == 'b') {
if (l != -1) {
if (r != n && s[l] == '(' && s[r] == ')') r ++;
l --;
}
} else {
if (r != n) r ++;
}
}
for (int i = 0; i <= l; i ++) cout << s[i];
cout << 'I';
for (int i = r; i < n; i ++) cout << s[i];
cout << endl;
}
D - 小苯的IDE括号问题(hard)
用两个栈模拟
cpp
void solve() {
cin >> n >> m >> s;
int idx = s.find('I');
stack<char> l, r, t;
for (int i = 0; i < idx; i ++) l.push(s[i]);
for (int i = n - 1; i > idx; i --) r.push(s[i]);
while (m --) {
string op; cin >> op;
if (op[0] == 'b') {
if (!l.empty()) {
if (!r.empty() && l.top() == '(' && r.top() == ')') r.pop();
l.pop();
}
} else if (op[0] == 'd') {
if (!r.empty()) r.pop();
} else if (op[0] == '<') {
if (!l.empty()) {
r.push(l.top());
l.pop();
}
} else {
if (!r.empty()) {
l.push(r.top());
r.pop();
}
}
}
while (!l.empty()) t.push(l.top()), l.pop();
while (!t.empty()) cout << t.top(), t.pop();
cout << 'I';
while (!r.empty()) cout << r.top(), r.pop();
cout << endl;
}
E - 小苯的数组构造
贪心,让 a [ i ] + b [ i ] = m a x j = 1 i − 1 a j a[i]+b[i]=max_{j=1}^{i-1}a_j a[i]+b[i]=maxj=1i−1aj
cpp
void solve() {
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i];
int Max = -1e9;
for (int i = 0; i < n; i ++) {
b[i] = max(0, Max - a[i]);
Max = max(Max, a[i]);
}
for (int i = 0; i < n; i ++) cout << b[i] << ' ';
cout << endl;
}
F - 小苯的数组切分
由于一个数如果给 ∣ | ∣ 操作只会多不会少,但是给 & \& & 操作只会少不会多,因此贪心地让 & \& & 操作只包含 a [ n ] a[n] a[n],接下来遍历一下前两个操作的分界点即可
cpp
ll solve() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i], b[i] = a[i] ^ b[i - 1];
ll res = 0, cnt = a[n - 1];
for (int i = n - 2; i; i --) {
res = max(res, cnt + b[i]);
cnt |= a[i];
}
return res + a[n];
}
G - 小苯的逆序对
树状数组维护逆序对, f [ i ] = n u m i ∣ a r r [ k ] − f [ 2 i ] − f [ 3 i ] − ... f [ ⌊ n i ⌋ i ] f[i]=num_{i|arr[k]}-f[2i]-f[3i]-...f[\left \lfloor \frac n i \right \rfloor i] f[i]=numi∣arr[k]−f[2i]−f[3i]−...f[⌊in⌋i]
其中逆序操作保证 f [ 2 i ] , f [ 3 i ] , ... ... f [ ⌊ n i ⌋ i ] f[2i],~f[3i],~......~f[\left \lfloor \frac n i \right \rfloor i] f[2i], f[3i], ...... f[⌊in⌋i] 是已经求得的
cpp
ll f[N];
struct BIT {
int tr[N];
inline int lowbit(int x) { return x & -x; }
void modify(int x, int k) {
while (x) tr[x] += k, x -= lowbit(x);
}
int query(int x) {
int res = 0;
while (x <= n) res += tr[x], x += lowbit(x);
return res;
}
} bit;
ll solve() {
cin >> n;
for (int i = 1; i <= n; i ++) {
int x; cin >> x;
a[x] = i;
}
for (int i = n; i; i --) {
for (int j = i; j <= n; j += i) {
f[i] += bit.query(a[j]);
bit.modify(a[j], 1);
}
for (int j = i; j <= n; j += i) {
bit.modify(a[j], -1);
if (j != i) f[i] -= f[j];
}
}
return f[1];
}