Codeforces Round 900 (Div. 3) A~F

A. How Much Does Daytona Cost?

#include 
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
void solve()
{
    int n, k;
    cin >> n >> k;
    // map s;
    // bool flag = false;
    // for (int i = 0; i < n; i++)
    // {
    //     int a;
    //     cin >> a;
    //     if (a == k)
    //     {
    //         flag = true;
    //     }
    // }
    // if (flag)
    // {
    //     cout << "YES" << endl;
    // }
    // else
    // {
    //     cout << "NO" << endl;
    // }

    vector a(n);
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    if (find(a.begin(), a.end(), k) != a.end())
    {
        cout << "YES" << endl;
    }
    else
    {
        cout << "NO" << endl;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

B. Aleksa and Stack

/*
方法一:暂时想不出怎么构造就直接暴力让计算机去算
方法二:1 3 5 7 9....这样的奇数序列,a[i]*3为奇数,a[i-1]+a[i-2]为偶数,当然不能整除
当然还有很多方法
*/
#include 
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
void solve()
{
    int n;
    cin >> n;
    vector a(n + 1);
    a[1] = 2, a[2] = 3;
    for (int i = 3; i <= n; i++)
    {
        a[i] = a[i - 1] + 1;
        while (3 * a[i] % (a[i - 1] + a[i - 2]) == 0)
        {
            a[i]++;
        }
    }
    for (int i = 1; i <= n; i++)
    {
        cout << a[i] << " \n"[i == n];
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

C. Vasilije in Cacak

//判断x在个数k时是不是越界了就行
#include 
using namespace std;

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        long long n, k, x;
        cin >> n >> k >> x;
        long long min_sum = k * (k + 1) / 2;
        long long max_sum = n * (n + 1) / 2 - (n - k) * (n - k + 1) / 2;
        if (min_sum <= x && x <= max_sum)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

D. Reverse Madness

/*
对于一次x操作,对于每一个区间l[i],r[i],都有(x,r[i]-l[i]+x)进行翻转,维护每个区间的翻转次数即可,直接每次翻转肯定会超时
*/
#include 
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
void solve()
{
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    vector l(n), r(n), f(n);
    for (int i = 0; i < k; i++)
    {
        cin >> l[i];
        l[i]--;
    }
    for (int i = 0; i < k; i++)
    {
        cin >> r[i];
        r[i]--;
    }
    int q;
    cin >> q;
    while (q--)
    {
        int x;
        cin >> x;
        x--;
        f[x] ^= 1; // 在标记的同时,去掉那些执行偶数次没有变的操作
    }
    for (int i = 0; i < k; i++) // 遍历每个[l[i],r[i]]
    {
        int rev = 0;
        for (int j = l[i]; j <= l[i] + r[i] - j; j++) // 逐步判断区间两端需不需要交换
        {
            rev ^= f[j] ^ f[l[i] + r[i] - j];
            /*
            如果f[j]=1,或者f[l[i] + r[i] - j]=1,说明[j,l[i]+r[i]-j]这个区间要翻转一次,那么可以知道只有在翻转一次时有效的,
            此时rev=1,表示该区间内的所有元素暂时都要翻转一次,现在确定的只有两端的元素翻转/交换,因为内部区间在j++后,区间[j+1,l[i]+r[i]-j-1]是否再进行翻转还不可知
            */
            if (rev)
            {
                // cout << j << " " << l[i] + r[i] - j << endl;
                swap(s[j], s[l[i] + r[i] - j]);
            }
        }
    }
    cout << s << endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

E. Iva & Pav

/*
前缀和二分,对于一个区间内,若某一位上的1的个数全为1,即1的个数=区间长度时,进行n次&操作还是1
二分性质:对于&与操作,与运算次数越多,值只会比原来小/相等,不会比原来的大,则从区间[l,r]是值递减的,满足单调性
*/
#include 
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
const int N = 2e5 + 5;
ll f[N][32];
ll a[N];
ll w[32];
void fun0()
{
    w[0] = 1;
    for (int i = 1; i < 32; i++)
    {
        w[i] = w[i - 1] * 2;
    }
}
void fun(int id) // 将给定的数化为32为二进制数
{
    ll x = a[id];
    for (int j = 0; j < 32; j++)
    {
        f[id][j] = f[id - 1][j];
        if (x % 2 == 1)
        {
            f[id][j]++;
        }
        x /= 2;
    }
}
ll ans, n, q, k;
ll check(ll l, ll r)
{
    ll x = 0, y = 1;
    for (int i = 0; i < 32; i++)
    {
        int p = f[r][i] - f[l - 1][i];
        if (p == r - l + 1)
        {
            x += y;
        }
        y *= 2;
    }
    return x;
}
void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        fun(i);
    }
    int q;
    cin >> q;
    while (q--)
    {
        ll l, k, mid;
        cin >> l >> k;
        ll l0 = l, r = n, ans = -1;
        while (l <= r)
        {
            mid = (l + r) / 2;
            if (check(l0, mid) >= k)
            {
                ans = mid;
                l = mid + 1;
            }
            else
            {
                r = mid - 1;
            }
        }

        cout << ans << " \n"[q == 0];
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    fun0();
    while (t--)
    {
        solve();
    }
    return 0;
}

F. Vasilije Loves Number Theory

/*
思路:当gcd(a,n)==1,则d(a*n)=d(n)*d(a);
所以要使原式成立,则d(n)*d(a)==n,即是否有n% d(n)==0成立
d(n),对于每一个数m,他有n个可选,他的取值有[0,n](不选---选n个)
n % d(n)的值,(a*b)%c==((a%c)*(b%c))%c;
对于非常大的n,直接做除法,有点行不通,转化为由其因数来求
*/

#include 
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
long long qpow(long long a, long long b, long long m)
{
    a %= m;
    long long res = 1;
    while (b > 0)
    {
        if (b & 1)
        {
            res = res * a % m;
        }
        a = a * a % m;
        b >>= 1;
    }
    return res % m;
}
map now, org; // 记录当前质因数,n的质因数
void solve()
{
    now.clear(); // 清空
    ll n, q, x;
    cin >> n >> q;
    x = n;
    for (int i = 2; i * i <= x; i++)
    {
        while (x % i == 0)
        {
            x /= i;
            now[i]++;
        }
    }
    if (x > 1)
    {
        now[x]++;
    }
    org = now; // 记录n的质子数
    while (q--)
    {
        int op;
        cin >> op;
        if (op == 1)
        {
            ll s;
            cin >> s;
            for (int i = 2; i * i <= s; i++)
            {
                while (s % i == 0)
                {
                    s /= i;
                    now[i]++; // n*s后新增的质因数
                }
            }
            if (s > 1)
            {
                now[s]++;
            }
            // 求d(n),对于每一个数m,他有n个可选,他的取值有[0,n](不选---选n个),所以总的因子有:
            ll ans = 1; // d(n)的质因子
            for (auto v : now)
                ans *= (v.second + 1);

            //(s*n)% ans=(s%ans)*(n%ans)%ans
            // 求n是否能整除d(n),即ans
            ll mod = 1;
            for (auto v : now)
                (mod *= qpow(v.first, v.second, ans)) %= ans;
            if (mod % ans == 0)
            {
                cout << "YES"
                     << "\n";
            }
            else
            {
                cout << "NO"
                     << "\n";
            }
        }
        else
        {
            now = org;
        }
    }
    cout << "\n";
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

你可能感兴趣的:(算法,c++)