AtCoder Beginner Contest 172 部分题解

Posted hznumqf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 172 部分题解相关的知识,希望对你有一定的参考价值。

C:给两个栈,每次只能取栈顶元素,取完后自动pop  问能取到最多几个元素

栈中元素之和必须小于等于K


官方题解给出的做法是O(N+M) 受上一场CF启发,此题可以很自然联想到二分做法。  二分答案,答案显然具有单调性。check函数只需遍历一遍可能情况

复杂度O((N+M)logX) 

技术图片
int n, m;
ll k;
ll a[maxn], b[maxn];
ll sum1[maxn];
ll sum2[maxn];

bool check(int x) {
    for (int i = x - m ; i <= min(x,n); i++) {
        if (sum1[i] + sum2[x - i] <= k) {
            //cout << x << " " << i <<" "<< x - i << endl;
            return 1;
        }
    }
    return 0;
}

int main() {
    scanf("%d%d%lld", &n, &m, &k);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", a + i );  sum1[i] = sum1[i - 1] + a[i];
    }
    for (int i = 1; i <= m; i++) {
        scanf("%lld", b + i); sum2[i] = sum2[i - 1] + b[i];
    }
    int l = 0, r = n + m;
    while (l < r) {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    if (check(l)) printf("%d", l);
    else printf("%d", l-1);
}
View Code

 

D:

函数F(x) 表示x的因子个数 。 求 sgma i*F(i)          N<=1e7

利用d(i)==(每个质因数的指数+1)的积 跑一遍素数筛顺便可筛出F函数,之后相乘即可

技术图片
int n;
ll d[maxn], minn[maxn], prime[maxn];
bool is[maxn];
int tot;

void init() {
    d[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        if (is[i] == 0) prime[++tot] = i, d[i] = 2, minn[i] = 1;
        for (re int j = 1; prime[j] * i <= n && j <= tot; j++)
        {
            is[i * prime[j]] = 1;
            if (i % prime[j] == 0)
            {
                minn[i * prime[j]] = minn[i] + 1;
                d[i * prime[j]] = d[i] / (minn[i] + 1) * (minn[prime[j] * i] + 1);
                break;
            }
            minn[i * prime[j]] = 1;
            d[i * prime[j]] = d[i] * 2;
        }
    }
}

int main() {
    scanf("%d", &n);
    init();
    ll res = 0;
    for (int i = 1; i <= n; i++) {
        res += i * d[i];
    }
    printf("%lld", res);
}
View Code

 

E:

构造一对数组a,b  要求满足 数组中数字均不超过M。 且 1.a中元素互不相同 2.b中元素互不相同 3.ai不等于bi  问可构造出多少对

1<=N<=M<=5e5

 

推公式即可  先把a数组定下来,有A(n,m) 种选法。 再考虑所有情况减去不对的情况。 故容斥(实际上是错排的推广) 

注意最后不对的情况要除以(m-n)!去重

技术图片

注意取逆元。

技术图片
ll inv[maxn];
ll n, m;

void inver(ll p) {
    inv[0] = 1;
    inv[1] = 1;
    for (int i = 2; i <= m; i++) {
        inv[i] = (p - p / i) * inv[p % i] % p;
    }
}


ll c[maxn];
ll fac[maxn];

ll quickPower(ll a, ll b, ll m) {   //计算a的b次方
    ll ans = 1;
    ll base = a;
    while (b) {
        if (b & 1) {
            ans *= base;
            ans %= m;
        }
        base *= base;
        base %= m;
        b >>= 1;   //注意是b>>=1 not b>>1
    }
    return ans;
}

ll get_inv(ll x) {
    return quickPower(x, MOD - 2, MOD);
}

void get_fac() {
    fac[0] = 1;
    for (int i = 1; i <= m; i++) {
        fac[i] = (fac[i - 1] * i)%MOD;
    }
}

void get_C(ll n) {
    c[0] = 1;
    for (int i = 0; i < n; i++) c[i + 1] = ((c[i] * (n - i)) % MOD * inv[i + 1]) % MOD;
}

int main() {
    scanf("%lld%lld", &n, &m);
    inver(MOD);
    get_fac();
    get_C(n);
    ll res = (1 * ((fac[m] * get_inv(fac[m - n])) % MOD * get_inv(fac[m - n])) % MOD)%MOD;
    ll tmp = fac[m];
    int f = 1;
    for (int i = 1; i <= n; i++) {
        tmp = (tmp + ((-1ll * f) * ((c[i] * fac[m - i]) % MOD))+MOD) % MOD;
        f *= -1;
    }
    //cout << res << tmp << endl;
    printf("%lld", (tmp * res) % MOD);
}
View Code

 

F:

NIm博弈  不同之处在于 后手者可以在游戏开始前取出第一堆中的若干个放到第二堆中 问最少放几个可以保证他必胜 若不能输出-1

2<=N<=300     1<=ai<=1e12

技术图片
ll a[305];
ll m, s;

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%lld", a + i);
    m = a[2];
    for (int i = 3; i < n; i++) m ^= a[i];
    s = a[0] + a[1];
    ll rem = s - m;
    if ((rem % 2) || (rem < 0)) {
        puts("-1");
        return 0;
    }
    rem /= 2;
    ll b = rem;
    int f = 1;
    for (ll i = 50; i >= 0; i--) {
        ll p = 1ll << i;
        if ((m & p) && (rem & p)) f = 0;
        if ((m & p) && ((b + p) <= a[0])) b += p;
    }
    b = a[0] - b;
    if ((b >= a[0]) || (b < 0)) f = 0;
    if (f) printf("%lld", b);
    else puts("-1");
}
View Code

 

以上是关于AtCoder Beginner Contest 172 部分题解的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Beginner Contest 234

AtCoder Beginner Contest 115 题解

AtCoder Beginner Contest 154 题解

AtCoder Beginner Contest 103

AtCoder Beginner Contest 228

AtCoder Beginner Contest 242