牛客小白月赛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;
}
posted @ 2024-02-16 23:05  0x3ea  阅读(9)  评论(0编辑  收藏  举报