[题解]牛客挑战赛76题解(施工中)

A-校园活动

思路

了解程度的总和才(9000),直接遍历分组数量,从(n)(1)遍历,一旦能够分组就输出.

因为(0)对分组数量没有影响,所以只存正整数,方便操作.

注意全是(0)的情况答案是(n)

代码

#include <bits/stdc++.h>

using namespace std;

int n, sum;
vector<int> arr;

int check(int num)
{
    if (sum % num) return 0;
    int tar = sum / num;
    int tmp = 0;
    for (int x : arr)
    {
        if (tmp > tar) return 0;
        if (tmp == tar) tmp = 0; 
        tmp += x;
    }
    return tmp == tar;
}

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n;++i)
    {
        char c;
        scanf(" %c", &c);
        if (c-'0') arr.push_back(c-'0');
        sum += c-'0';
    }

    if (sum == 0) 
    {
        printf("%d
", n);
    }else{
        int ans = arr.size();
        while (ans > 1)
        {
            if (check(ans)) break;
            ans--;
        }
        if (ans < 2) printf("-1
");
        else printf("%d
", ans);
    }
}

C-CG的通关秘籍

思路

列出所有情况可以发现一共有(m^n)种.

当他填第(k, kin[1,n))位数字的时候,这样考虑贡献.

任何数字在第(k)位上出现的概率都是(frac{1}{m}).

所以对于每一个数字(p, pin[1,m]), 有(frac{m^n}{m}=m^{n-1})种情况第(k)位是(p).

在这(m^{n-1})种情况中,任何数字在(k+1)位上出现的概率都是(frac{1}{m}).

所以对于每一个数字(q,qin[1,m]),有(frac{m^{n-1}}{m}=m^{n-2})种情况第(k)位是(p)并且第(k+1)位是(q).

考虑每一对可能的(p,q)

(p<q)的情况有(frac{m*(m-1)}{2}*m^{n-2})种,贡献是(frac{m(m-1)}{2}*m^{n-2})

(p>q)的情况有(frac{m*(m-1)}{2}*m^{n-2})种,贡献是(frac{2m(m-1)}{2}*m^{n-2})

所以第(k)位的贡献是(frac{3m(m-1)}{2}*m^{n-2})

最后一位数字的后面没有东西,所以他没有贡献

最终答案是(frac{3m(m-1)}{2}*m^{n-2}*(n-1))

要用快速幂求(m^n-2)(2)的逆元.

代码

#include <bits/stdc++.h>

using namespace std;

const int p = 1e9+7;

int read()
{
    static char c = 0;
    int ret = 0;
    while (c <'0' || c > '9') c = getchar();
    while ('0' <= c && c <= '9')
    {
        ret = ret * 10 + c -'0';
        c = getchar();
    }
    return ret;
}

int qpow(int a, int x)
{
    int ret = 1;
    while (x)
    {
        if (x&1) ret = 1ll * ret * a % p;
        a = 1ll * a * a % p;
        x >>= 1;
    }
    //printf("%d
", ret);
    return ret;
}

int main()
{
    int t = read();
    while (t--)
    {
        int n = read(), m = read();
        printf("%lld
", 3ll * (n-1) % p * qpow(m, n-2) % p 
                            * m % p * (m-1) % p * qpow(2, p-2) % p);
    }
}

E-牛牛数数

思路

题目要求每个(x)只计算一次,每个(x)都是由说给的数字异或产生的.

给了(10^5)个数字,可以构造一个线性基

线性基有以下特性

  1. 线性基的元素之间互相异或构造出来的集合,与原本数组的元素之间相互异或构造出来的集合相同,对于本题,这个性质保证不遗漏
  2. 线性基中选择不同的子集,异或出来的数字都是不同的,对于本题,这个性质保证不重复计算
  3. 线性基是满足以上性质的最小集合,通常元素数量不大于数字的二进制位数,对于本题,线性基顶多会有(60)个元素
  4. 线性基各个元素的最高位(1)互不相同

所以我们先求出线性基.

然后用一个操作改变线性基,使得满足以下性质

任意一个元素(x),对于其他所有小于他的元素(y),如果(y)的最高位(1)位于第(p)位,那么(x)的第(p)位一定为(0).

然后从大到小排序.

设置一个变量(v=0).

从大到小遍历线性基的每个元素.

情况1

如果线性基的当前元素异或(v)的值大于(K).因为任意一个元素(x),对于其他所有小于他的元素(y),如果(y)的最高位(1)位于第(p)位,那么(x)的第(p)位一定为(0).

所以之后的值无论如何选择,(v)都会不会变小,所以最终产生的(x)一定大于(K).

那么当取这个元素之后,后面每个元素都可以取或者不取,对答案的贡献就是(2^{还未被遍历的元素的个数}).

但是不要直接把这个元素异或(x),因为取这个元素的方案已经考虑完了,之后(v)都是不带这个元素的.

情况2

如果线性基的当前元素异或(v)的值小于(K).那么不取这一个元素的情况一定不会有贡献.

因为后面的元素的(1)的最高位不会高过这一个元素,所以不取这一个元素的话,后面怎么取叶不会比(K)大.

取了这个元素的情况下有没有贡献我们还不知道,要到考虑后面的元素才能知道,这里先把这个元素异或(v).

代码

#include <bits/stdc++.h>

using namespace std;

long long read()
{
    static char c = 0;
    long long ret = 0;
    while (c <'0' || c > '9') c = getchar();
    while ('0' <= c && c <= '9')
    {
        ret = ret * 10 + c -'0';
        c = getchar();
    }
    return ret;
}



int main()
{
    int n = read();
    long long K = read();
    long long ans = 0, v = 0;
    vector<long long> base;
    for (int i = 1; i <= n; ++i)
    {
        long long x = read();
        for (long long y : base) x = min(x, x^y);
        if (x) base.push_back(x);
    }

    for(int i = 0; i < base.size(); i++)
        for(int j = 0; j < base.size(); j++)
            if(i != j)
                base[i] = min(base[i], base[i] ^ base[j]);

    sort(base.begin(), base.end(), greater<long long>());
    //for (long long x : base) printf("%lld
", x);
    for (int j = 0; j < base.size(); ++j)
    {
        if ((v ^ base[j]) > K)
            ans += 1ll << (base.size() - j - 1);
        else
            v ^= base[j];
    }
    printf("%lld
", ans);
}
原文地址:https://www.cnblogs.com/zzidun-pavo/p/14288885.html