正睿二轮省选day1

期望:100+16+8

实际:0+16+8

T1:

  最后的二分找每个1的位置写没了,本机上测爆longlong会到负数,但正睿的机子不是,判错了,直接爆0

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long LL;

const int N = 100010;
const int mod = 998244353;
const LL INF = 1e18 + 1;

LL n, K;
LL C[75][N], len[75];

inline int dec(int x, int y) { return x < y ? x - y + mod : x - y; }
inline void add(int& x, int y) { x += y; if (x >= mod)x -= mod; }

inline LL qpow(LL a, LL k, LL p = mod)
{
    LL res = 1;
    while (k)
    {
        if (k & 1) res = res * a % mod;
        a = a * a % mod;
        k >>= 1;
    }
    return res;
}

inline LL check(LL n, LL m)
{
    if (m >= 4) return n > len[m] ? INF : C[m][n];
    else 
    {
        __int128 c = 1;
        for (int i = 0; i < m; ++i)
        {
            c *= n - i, c /= i + 1;
            if (c > 1e18)return INF;
        }
        return c;
    }
}

int main() 
{
    int T;
    scanf("%d", &T);
    for (LL i = 4;; i++)
    {
        C[4][i] = i * (i - 1) / 2 * (i - 2) / 3 * (i - 3) / 4;
        if (C[4][i] > 1e18) { len[4] = i - 1; break; }
    }

    for (int i = 5; i <= 70; ++i) 
    {
        for (LL j = i;; ++j)
        {
            C[i][j] = C[i - 1][j - 1] + C[i][j - 1];
            if (C[i][j] > 1e18) { len[i] = j - 1; break; }
        }
    }

    while (T--) 
    {
        scanf("%lld%lld", &n, &K);
        LL k = (sqrt(8 * n - 7) - 1) / 2;
        LL a = n - k * (k + 1) / 2;

        if (k - a == -1)
        {
            if (K == 1) printf("%d\n", dec(qpow(2, k + 1), 1));
            else puts("-1");
        }
        else if (k - a >= 61 || (1ll << (k - a)) >= K) 
        {
            int ans = dec(qpow(2, k + 1), qpow(2, k + 1 - a));
            if (k == a) printf("%d\n", ans);
            else
            {
                LL s = 0, i;
                __int128 c = 1;
                for (i = 0;; ++i)
                {
                    if (c >= K || (s + c) >= K)break;
                    s += c, c *= k - a - i, c /= i + 1;
                }

                K -= s, --K;

                for (LL j = i, lim = k - a - 1; j >= 1; --j)
                {
                    LL lb = j - 1, rb = lim, mid, ret;
                    if (j > 4) rb = min(rb, len[j]);
                    while (lb <= rb)
                    {
                        mid = (lb + rb) >> 1;
                        if (check(mid, j) <= K) lb = mid + 1, ret = mid;
                        else rb = mid - 1;
                    }
                    lim = ret - 1, K -= check(ret, j);

                    add(ans, qpow(2, ret));
                }
                printf("%d\n", ans);
            }
        }
        else puts("-1");
    }
    return 0;
}
View Code

T2:

  考场上看出来了,SAM模板题,但是我不会写,只写了暴力

#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;

#define mp make_pair

typedef long long LL;
typedef pair<int, int> PII;

const int N = 50010;

map<PII, int> vis;

struct String
{
    int siz, last;
    string str;

    struct Node
    {
        int len, link;
        map<char, int> nex;
        Node() {}
    };

    map<int, Node> st;

    void sam_extend(char c)
    {
        int cur = siz++;
        st[cur].len = st[last].len + 1;
        int p = last;
        while (p != -1 && !st[p].nex.count(c))
        {
            st[p].nex[c] = cur;
            p = st[p].link;
        }
        if (p == -1)
        {
            st[cur].link = 0;
        }
        else
        {
            int q = st[p].nex[c];
            if (st[p].len + 1 == st[q].len)
            {
                st[cur].link = q;
            }
            else
            {
                int clone = siz++;
                st[clone].len = st[p].len + 1;
                st[clone].nex = st[q].nex;
                st[clone].link = st[q].link;
                while (p != -1 && st[p].nex[c] == q)
                {
                    st[p].nex[c] = clone;
                    p = st[p].link;
                }
                st[q].link = st[cur].link = clone;
            }
        }
        last = cur;
    }

    inline void init()
    {
        st[0].len = 0;
        st[0].link = -1;
        siz++, last = 0;
    }

    inline void New()
    {
        cin >> str;
        init();
        for (int i = 0; i < str.size(); i++) sam_extend(str[i]);
    }

    inline int find(string T)
    {
        int v = 0, l = 0, best = 0, bestpos = 0;
        for (int i = 0; i < T.size(); i++)
        {
            while (v && !st[v].nex.count(T[i])) 
            {
                v = st[v].link;
                l = st[v].len;
            }
            if (st[v].nex.count(T[i])) 
            {
                v = st[v].nex[T[i]];
                l++;
            }
            if (l > best)
            {
                best = l;
                bestpos = i;
            }
        }
        return best;
    }
};

map<int, String> S;
int n;

int main()
{
    int q;
    scanf("%d%d", &n, &q);

    for (int i = 0; i < n; i++) S[i].New();

    while (q--)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        if (S[a].str.size() > S[b].str.size()) swap(a, b);
        if (vis[mp(a, b)]) printf("%d\n", vis[mp(a, b)]);
        else printf("%d\n", vis[mp(a, b)] = S[b].find(S[a].str));
    }
    return 0;
}
View Code

T3:

  不会

posted on 2021-02-19 19:52  ArrogHie  阅读(127)  评论(0)    收藏  举报