题解ABC300 F,G

Posted linyihdfj

tags:

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

【题解】ABC300 F,G

F.More Holidays

题目分析:

考虑刻画一下我们选择是什么样子的。
考虑我们最后选择的 \\(T\\) 中的一段一定是形如:一个完整的 S 选择一个后缀 \\(+\\) 若干个完整的 S \\(+\\) 一个完整的 S 的前缀。
这样的话就启示我们直接枚举这个前后缀选择的是什么,然后就可以很快算出来了,但是枚举前后缀是 \\(O(n^2)\\) 的。
考虑优化,其实枚举两个实在是太亏了,考虑只枚举一个可不可以。
假设我们只枚举第一个 S 的删去哪一个前缀,其实就是选择哪一个后缀,假设这个必须要删去的前缀里有 \\(t\\) 个 x,那么其实也就是说我们从 T 的前缀里最多选择 \\(t + k\\) 个 x,询问最多使得多少个 o 联通,这个就是直接二分就可以完成了。

G.P-smooth number

题目分析:

看到 \\(P\\) 那么小,显然可以想到直接搜出来有哪些素数,然后就是枚举这些素数各自选了多少个。
这样看上去复杂度并不是很劣,因为我们选择的总个数不会超过 \\(\\log_2 n\\)
但是其实看一下样例就知道,直接爆搜是不行的,因为最劣有 \\(2\\times 10^9\\) 个答案。
但是看到答案数其实不是很多,所以就其实我们直接记忆化,也就是说对于 \\(n\\) 比较小的情况的方案数记下来,以后直接用。
大概记到 \\(10^6\\) 就可以通过这个题了。

题解 AtCoder abc154 F

题目大意(f(r,c)=C_{r+c}^r),要求输出 (sum_{i=r_1}^{r_2}sum_{j=c_1}^{c_2} f(i,j)),其中 (r_2,r_2,c_1,c_2) 为给定值。

分析

[g(r,c)=sum_{i=0}^rsum_{j=0}^c f(i,j)]

则题目所求为

[sum_{i=r_1}^{r_2}sum_{j=c_1}^{c_2} f(i,j)=g(r_2,c_2)-g(r_2,c_1-1)-g(r_1-1,c_2)+g(r_1-1,c_1-1)]

如果我们能快速计算 (g) 则就解决了问题。

现在我们考虑如何用 (f(r,cdots)) 求出 (f(r+1,c)),我们有

[f(r+1,c)-f(r,c)=C_{r+1+c}^{r+1}-C_{r+c}^r=frac{(r+c+1)!}{(r+1)!c!}-frac{(r+c)!}{r!c!}=frac{(r+c+1)!-(r+c)!(r+1)}{(r+1)!c!}=frac{(r+c)![(r+c+1)-(r+1)]}{(r+1)!c!}=frac{(r+c)!}{(r+1)!(c-1)!}=f(r+1,c-1)]

也就是说,我们有递归式

[f(r+1,c)=f(r,c)+f(r+1,c-1)=f(r,c)+f(r,c-1)+f(r+1,c-2)=cdots=f(r,c)+f(r,c-1)+f(r,c-2)+cdots+f(r,0)=sum_{i=0}^cf(r,i)]

那么

[g(r,c)=sum_{i=0}^rsum_{j=0}^c f(i,j)=sum_{i=0}^rf(i+1,c)=sum_{i=0}^rf(c,i+1)=f(c+1,r+1)-1]

那么代码就很简单了。

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int mod = 1e+9 + 7;

ll r1, r2, c1, c2;

ll qPow(ll a, ll b)
{
    a %= mod;
    
    ll res = 1;
    while(b) {
        if(b & 1) res = res * a % mod;
        a = a * a % mod, b >>= 1;
    }
    return res;
}

ll C(ll n, ll m)
{
    if(n < m) return 0;
    
    ll res = 1;
    for(int i = 1; i <= m; ++i)
        res = res * (n - i + 1) % mod * qPow(i, mod - 2) % mod;
    return res;
}

int main()
{
    scanf("%lld%lld%lld%lld", &r1, &c1, &r2, &c2);
    
    ++r2, ++c2;
    printf("%lld", ((C(r2 + c2, c2) - C(r1 + c2, c2) - C(r2 + c1, c1) + C(r1 + c1, c1)) % mod + mod) % mod);
}

以上是关于题解ABC300 F,G的主要内容,如果未能解决你的问题,请参考以下文章

abc270_f Transportation 题解

AtCoder abc256全题解(区间合并模板矩阵快速幂优化dp线段树……)

AtCoder abc256全题解(区间合并模板矩阵快速幂优化dp线段树……)

abc269_f Numbered Checker 题解

AT_abc139f 题解

一篇关于模拟退火的题解,abc157 F Yakiniku Optimization Problem