牛客小白月赛87
A
void solve()
{
int n;
cin >> n;
vector<ll> a(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
ll chk = 0;
for (int i = n; i >= 1; i--)
{
if (i % 2 == n % 2)
chk += a[i];
else
chk -= a[i];
}
cout << (chk > 0 ? "Alice" : "Bob") << endl;
}
B
void solve()
{
int n;
cin >> n;
vector<ll> a(n + 1, 0), b(n + 1, 0);
for (int i = 1; i <= n; i++)
cin >> a[i], b[i] = a[i];
sort(b.begin() + 1, b.end());
int l = 1, r = n;
while (l <= n && a[l] == b[l])
l++;
while (r >= 1 && a[r] == b[r])
r--;
if (l == 1 && r == n)
cout << "NO" << endl;
else
cout << "YES" << endl;
}
C/D
set模拟
void solve()
{
int n, k, pos;
cin >> n >> k;
set<int> s;
string str;
cin >> str;
str = '#' + str;
for (int i = 1; i <= n; i++)
{
s.insert(i * 2 - 1);
if (str[i] == 'I')
pos = 2 * i - 1;
}
string opt;
for (int i = 1; i <= k; i++)
{
cin >> opt;
auto t = s.lower_bound(pos);
if (opt == "backspace")
{
if (t != s.begin())
{
auto fi = prev(t);
if (next(t) != s.end())
{
auto se = next(t);
if (str[*fi / 2 + 1] == '(' && str[*se / 2 + 1] == ')')
s.erase(fi), s.erase(se);
else
s.erase(fi);
}
else
s.erase(fi);
}
}
else if (opt == "delete")
{
if (next(t) != s.end())
{
auto se = next(t);
s.erase(se);
}
}
else if (opt == "<-")
{
if (t != s.begin())
{
auto fi = prev(t);
pos = *fi - 1;
s.erase(t), s.insert(pos);
}
}
else //->
{
if (next(t) != s.end())
{
auto se = next(t);
pos = *se + 1;
s.erase(t), s.insert(pos);
}
}
}
for (auto i : s)
{
if (i != pos)
cout << str[i / 2 + 1];
else
cout << 'I';
}
cout << endl;
}
stack模拟
void solve()
{
int n, k;
cin >> n >> k;
string s, opt;
cin >> s;
vector<char> s1, s2;
for (int i = 0; i < s.size() && s[i] != 'I'; i++)
s1.push_back(s[i]);
for (int i = s.size() - 1; i >= 0 && s[i] != 'I'; i--)
s2.push_back(s[i]);
for (int i = 1; i <= k; i++)
{
cin >> opt;
if (opt == "backspace")
{
if (s1.size() && s2.size() && s1.back() == '(' && s2.back() == ')')
s1.pop_back(), s2.pop_back();
else
{
if (s1.size())
s1.pop_back();
}
}
else if (opt == "delete")
{
if (s2.size())
s2.pop_back();
}
else if (opt == "<-")
{
if (s1.size())
s2.push_back(s1.back()), s1.pop_back();
}
else //->
{
if (s2.size())
s1.push_back(s2.back()), s2.pop_back();
}
}
for (auto i : s1)
cout << i;
cout << 'I';
reverse(s2.begin(), s2.end());
for (auto i : s2)
cout << i;
}
双链表模拟
void solve()
{
int n, k, pos;
cin >> n >> k;
string s, opt;
cin >> s;
s = '#' + s;
vector<int> l(n + 0, 0), r(n + 10, 0);
for (int i = 1; i <= n; i++)
l[i] = i - 1, r[i] = i + 1;
r[n] = 0;
for (int i = 1; i <= n; i++)
if (s[i] == 'I')
pos = i;
for (int i = 1; i <= k; i++)
{
cin >> opt;
if (opt == "backspace")
{
if (s[l[pos]] == '(' && s[r[pos]] == ')')
{
int L = l[l[pos]], R = r[r[pos]];
r[L] = pos, l[R] = pos;
l[pos] = L, r[pos] = R;
}
else
{
if (l[pos])
{
int L = l[l[pos]];
r[L] = pos, l[pos] = L;
}
}
}
else if (opt == "delete")
{
if (r[pos])
{
int R = r[r[pos]];
l[R] = pos, r[pos] = R;
}
}
else if (opt == "<-")
{
if (l[pos])
swap(s[pos], s[l[pos]]), pos = l[pos];
}
else //->
{
if (r[pos])
swap(s[pos], s[r[pos]]), pos = r[pos];
}
}
while (l[pos])
pos = l[pos];
while (pos)
{
cout << s[pos];
pos = r[pos];
}
}
E
要使数组非递减,那么一定要把逆序给变成非递减,其他地方答案就是0(如果是其他值的话,可能会影响非递减的性质)
void solve()
{
int n;
cin >> n;
vector<ll> a(n + 1, 0), b(n + 1, 0);
ll mx = -1e18;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
mx = max(mx, a[i]);
}
for (int i = 2; i <= n; i++)
if (a[i] < a[i - 1])
{
b[i] = a[i - 1] - a[i];
a[i] = a[i - 1];
}
for (int i = 1; i <= n; i++)
cout << b[i] << " ";
cout << endl;
}
F
注意到and一定是递减的,所以只取一个,然后枚举xor与or的分界点即可
void solve()
{
int n;
cin >> n;
vector<ll> a(n + 1, 0);
for (int i = 1; i <= n; i++)
cin >> a[i];
ll sumxor = 0;
ll sumor = a[n - 1];
ll ans = 0;
for (int i = 1; i <= n - 2; i++)
sumxor ^= a[i];
ans = sumxor + sumor + a[n];
for (int i = n - 2; i > 1; i--)
{
sumxor ^= a[i];
sumor |= a[i];
ans = max(ans, sumxor + sumor + a[n]);
}
cout << ans << endl;
}
G
处理出1-n每个数的倍数的子序列g
比如原数组是2 4 3 5 1
\(g_1={2 ,4 ,5 ,3 ,1}\)
\(g_2={2 ,4 }\)
\(g_3=3\)
\(g_4={4}\)
\(g_5={5}\)
这样对每个子序列用树状数组求逆序对就可以得到gcd(a,b)=x的倍数,的答案
然后再利用容斥得到gcd(i,j)=x的答案
#include <bits/stdc++.h>
#define endl '\n'
#define x first
#define y second
#define ls(x) (a[x].l)
#define rs(x) (a[x].r)
#define sum(x) a[x].sum
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef double db;
const ll mod = 998244353;
const int N = 2e5 + 10, M = 21;
random_device rd;
mt19937_64 gen(rd());
struct BIT
{
int n;
vector<int> a;
BIT(int _n) : n(_n), a(n + 3, 0) {}
int lb(int x) { return x & -x; }
void add(int x, ll y)
{
for (; x <= n; x += lb(x))
a[x] += y;
}
ll query(int x)
{
ll res = 0;
for (; x; x ^= lb(x))
res += a[x];
return res;
}
};
void solve()
{
int n;
cin >> n;
vector<ll> dp(N, 0); // gcd(a,b)=i,且是逆序对的数量
vector<vector<int>> fac(N), g(n + 1); // fac 表示所有因数,g表示所有倍数
for (int i = 1; i <= 2e5; i++)
for (int j = i; j <= 2e5; j += i)
fac[j].push_back(i);
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
for (auto f : fac[x]) // x是哪些数的倍数
g[f].push_back(x);
}
for (int i = 1; i <= n / 2; i++) // 枚举gcd
{
int sz = n / i;
BIT bit(sz + 1);
for (int j = g[i].size() - 1; j >= 0; j--) // 求逆序对
{
int u = g[i][j] / i;
dp[i] += bit.query(u - 1);
bit.add(u, 1);
}
}
for (int i = n / 2; i >= 1; i--)
for (int j = 2 * i; j <= n; j += i)
dp[i] -= dp[j];
cout << dp[1] << endl;
}
int main()
{
// cout << setprecision(5);
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int _ = 1;
// cin >> _;
while (_--)
solve();
return 0;
}