[5-28,5-29]考试总结

day1

T1
需要考虑的地方:给定一个字符串,再给定另一个串,只有小写字母,如何在线性时间内匹配出一个子序列等于所给定的第二个串。
做法:设dp[i][k]表示在第一个串中,从i开始下一个k字符的位置,先预处理dp,按着这个指针直接跳即可。
T2
需要考虑的地方:如何求出一个序列的最长上升子序列必须用到的数。
做法:处理出d[i]数组,即以i结尾的最长上升子序列长度,把长度等于ans的加入集合中,然后往前面扫d[i]=ans-1的,若只有一个则这个是必须的,然后递归ans-2…
T3
需要考虑的地方:把有向边(u,v)变成无向边之后,包含这条边的强联通分量怎么求。
做法:缩点后,用bitset存下每个点的能到的点f1,能到这个点的点f2,则强联通分量就是f1[u]&f2[v],因为v又能连回u。

day2

三道模板题,高精度取余,FFT,斜率优化。
这里贴FFT代码:

void fft_init(int CN)
{
     for (N = 1, STEP = 0; N < CN; N <<= 1, ++STEP) { }

    for (int i = 0; i < N; ++i) {
        rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (STEP - 1));
    }
}
void fft(Complex a[],int flag)
{
    for (int i = 0; i < N; ++i) {
        if (i < rev[i])
            std::swap(a[i], a[rev[i]]);
    }

    for (int k = 1; k < N; k <<= 1) {
        Complex wk(cos(PI / k), flag * sin(PI / k));
        for (int i = 0; i < N; i += (k << 1)) {
            Complex wkj = Complex(1.0, 0.0);
            for (int j = 0; j < k; ++j) {
                Complex x = a[i + j];
                Complex y = a[i + j + k] * wkj;
                a[i + j] = x + y;
                a[i + j + k] = x - y;

                wkj = wkj * wk;
            }
        }
    }

    if (flag == -1) {
        for (int i = 0; i < N; ++i) {
            a[i].x /= N;
        }
    }
}

需要注意的地方,开好longlong!

你可能感兴趣的:(考试总结,FFT)