2020杭电多校第一场

1004.Distinct Sub-palindromes

签到题,问长度为n且回文子串的个数最少的串的数量

想到 abcabcabc... 排列回文子串最少为3

n=1,2,3特殊处理一下

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)

ll n;
void solve()
{
    cin >> n;
    if (n == 1)
        puts("26");
    else if (n == 2)
        puts("676");
    else if (n == 3)
        cout << 26 * 26 * 26 << endl;
    else
        cout << 26 * 25 * 24 << endl;
}
int main()
{

    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
View Code

 

1005. Fibonacci Sum

题意:求这个式子

先化简这个式子,根据斐波拉契通项:

化简完毕,求x2 ≡ 5(mod 1e9+9)得 x=383008016(二次剩余)

所以可求得1/√5 ≡ 276601605(mod 1e9+9),a ≡ 691504013(mod 1e9+9), b ≡ 308495997(mod 1e9+9)

求A,B,qn的时候用欧拉降幂即可,还有亿点点小细节看代码。(代码t了,大佬能指点一下吗)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)

int mod = 1e9 + 9;
inline int ksm(int a, int b)
{
    int res = 1;
    for (; b; b >>= 1, a = (ll)a * a % mod)
        if (b & 1)
            res = (ll)res * a % mod;
    return res;
}
int fac[100010], inv[100010];
inline int C(int k, int j) { return (ll)fac[k] * inv[j] % mod * inv[k - j] % mod; }
int x = 383008016, x2 = 276601605, a = 691504013, b = 308495997;
int A, B, q, Q, d, D, tmp; //Q = q ^ (n + 1), d = B / A, D = d ^ (n + 1)
ll n, c, k;
int ans;
inline void solve()
{
    cin >> n >> c >> k;
    ans = 0;
    A = ksm(a, c % (mod - 1));
    B = ksm(b, c % (mod - 1));
    q = ksm(A, k);
    Q = ksm(q, (n + 1) % (mod - 1));
    d = (ll)ksm(A, mod - 2) * B % mod;
    D = ksm(d, (n + 1) % (mod - 1));
    rep(j, 0, k)
    {
        tmp = q == 1 ? n % mod : (ll)(Q - q + mod) % mod * ksm(q - 1, mod - 2) % mod;
        tmp = (ll)tmp * C(k, j) % mod;
        tmp *= j & 1 ? -1 : 1;
        ans = (ans + tmp + mod) % mod;
        q = (ll)q * d % mod;
        Q = (ll)Q * D % mod;
    }
    cout << (ll)ksm(x2, k) * ans % mod << endl;
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    fac[0] = inv[0] = 1;
    rep(i, 1, 100000) fac[i] = (ll)fac[i - 1] * i % mod;
    inv[100000] = ksm(fac[100000], mod - 2);
    for (int i = 99999; i > 0; i--)
        inv[i] = (ll)inv[i + 1] * (i + 1) % mod;

    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
View Code

 

1009.Leading Robots

要判断哪些robot能领先。

先对加速度从大到小排序,再舍掉初始位置比之前小的(加速度小,初始位置小不可能追上)

这样后面的bot一定能追上前面的bot,然后如果当前bot在追上下一个bot之前就被追上了,那么他也要被舍弃

最后再排除掉初始位置和加速度相同的bot

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)

#define pii pair<int, int>
struct rob
{
    ll a, p;
    bool operator<(rob &f) const { return a == f.a ? p > f.p : a > f.a; }
} c[50010], tmp[50010], frot[50010];

double tim(rob x, rob y) { return 1.0 * (x.p - y.p) / (x.a - y.a); }

int n;
map<pair<int, int>, int> mp;
ll s, cnt, id, ans;
void solve()
{
    mp.clear();
    cin >> n;
    rep(i, 1, n)
    {
        cin >> c[i].a >> c[i].p;
        mp[make_pair(c[i].a, c[i].p)]++;
    }
    sort(c + 1, c + n + 1);
    s = cnt = id = ans = 0;
    rep(i, 1, n) if (c[i].p > s)
    {
        s = c[i].p;
        tmp[++cnt] = c[i];
    }
    rep(i, 1, cnt)
    {
        while (id > 1 && tim(tmp[i], frot[id]) <= tim(frot[id], frot[id - 1]))
            id--;
        frot[++id] = tmp[i];
    }
    rep(i, 1, id) if (mp[make_pair(frot[i].a, frot[i].p)] == 1) ans++;
    cout << ans << endl;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
View Code

 

1011.Minimum Index

求字符串每个前缀的最小后缀。

涉及到 Lyndon Word

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)

int mod = 1e9 + 7;
int n;
int ans[1000010];
int sum, tmp;
void solve()
{
    string s;
    cin >> s;
    n = s.length();
    sum = 1;
    tmp = 1112;
    int k = 0;
    while (k < n)
    {
        int i, j;
        ans[k] = k;
        for (i = k, j = i + 1; j < n && s[j] >= s[i]; j++)
            if (s[j] > s[i])
                ans[j] = i = k;
            else
            {
                ans[j] = ans[i] + j - i;
                i++;
            }
        while (k <= i)
            k += j - i;
    }
    rep(i, 1, n - 1)
    {
        sum = (sum + 1ll * (ans[i] + 1) * tmp) % mod;
        tmp = (tmp * 1112ll) % mod;
    }
    cout << sum << endl;
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
View Code

 

posted @ 2020-07-22 13:50  若讷  阅读(314)  评论(0编辑  收藏  举报