「2019纪中集训Day5」解题报告

T1、跳房子

game1.png
game2.png
game3.png

\(Sol\)
可以单独考虑一个点进行两种不同的操作后对答案的贡献,随便推一推就能算了。
或者可以把行列的操作分开算,不难发现行的和是个等差数列(列也一样),只需要先进行(xing)行(hang)操作,维护每一列的和的首项和公差即可;
时间复杂度 \(O(m)\)

代码如下:

//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
#include <cstdio>
#include <cstring>
#include <algorithm>
int in() {
    int x = 0; char c = getchar(); bool f = 0;
    while (c < '0' || c > '9')
        f |= c == '-', c = getchar();
    while (c >= '0' && c <= '9')
        x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return f ? -x : x;
}
template<typename T>inline void chk1(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk2(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 1e6 + 5, Q = 1e5 + 5, mod = 1e9 + 7;

int n, m, q;
struct info {
    int typ;
    int x, k;
} a[Q];
int x[N], y[N];

inline void add(int &_, int __) {
    _ += __;
    if (_ >= mod) _ -= mod;
    if (_ < 0)    _ += mod;
}

int main() {
    //freopen("in", "r", stdin);
    freopen("game.in", "r", stdin);
    freopen("game.out", "w", stdout);
    n = in(), m = in(), q = in();
    for (int i = 1; i <= q; ++i) {
        char c = getchar();
        while (c != 'R' && c != 'S')
            c = getchar();
        a[i] = (info){c == 'R', in(), in()};
    }
    
    int d = n;
    for (int i = 1; i <= n; ++i)
        x[i] = 1;
    
    if (n & 1)
        y[1] = 1ll * (1ll * (n - 1) / 2 * m + 1) % mod * n % mod;
    else
        y[1] = 1ll * (1ll * (n - 1) * m + 2) % mod * (n / 2) % mod;
    
    for (int i = 1; i <= q; ++i)
        if (a[i].typ) {
            add(y[1], 1ll * (1 + 1ll * (a[i].x - 1) * m % mod) * x[a[i].x] % mod * (a[i].k - 1) % mod);
            add(d, 1ll * (a[i].k - 1) * x[a[i].x] % mod);
            x[a[i].x] = 1ll * x[a[i].x] * a[i].k % mod;
        }
    
    for (int i = 2; i <= m; ++i)
        y[i] = y[i - 1], add(y[i], d);
    for (int i = 1; i <= q; ++i)
        if (!a[i].typ)
            y[a[i].x] = 1ll * y[a[i].x] * a[i].k % mod;
    for (int i = 1; i <= m; ++i)
        add(y[0], y[i]);
    printf("%d\n", y[0]);
    return 0;
}

T2、跳房子

game.png
game_input.png

\(Sol\)
考虑优化暴力找循环节,记录每个点会走到第 \(m\) 列的哪一个位置,修改时找到第一列中会改变的区间即可;
时间复杂度 \(O((m + n)\ Q)\)

代码(咕)

T3、优美序列

sequence1.png
sequence2.png

先咕着,

猜你喜欢

转载自www.cnblogs.com/15owzLy1-yiylcy/p/11305840.html