Atcoder Begnner Contest 253 (E,F)

E - Distance Sequence

思路:

考虑动态规划,前i项以j结尾的个数,第i-1项一定是上一项结尾小于等于j-k的个数+上一项结尾大于等于j+k的个数

代码:

#include <bits/stdc++.h>
#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
 
const int N = 1010, M = 5 * N, mod = 998244353;
int f[N][M];
int s[N];
void solve(int Case) {
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 1; i <= m; i++) f[1][i] = 1;
    for (int i = 1; i <= m; i++) f[1][i] += f[1][i - 1];
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            int low = j - k;
            int up = j + k;
            if (up == low) up++;
            if (low >= 0)
                f[i][j] =(f[i][j]+ f[i - 1][low])%mod;
            f[i][j] %= mod;
            if (up <= m)
                f[i][j] =(f[i][j]+ (f[i - 1][m] - f[i - 1][up - 1]+mod)%mod)%mod;
            f[i][j] %= mod;
        }
        for (int j = 1; j <= m; j++) {
            f[i][j] += f[i][j - 1];
            f[i][j] %= mod;
        }
    }
    cout << f[n][m] << nline;
 
 
 
 
}
 
signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
//   for (cin>>_, Case = 1; Case <= _; Case++)
    solve(Case);
 
    return 0;
}

F - Operations on a Matrix

思路:

求操作3时,可以计算出第j列累加的值s,第i行最后一次变的值x,还有变成x的时候第j列累加的值s1,结果就是x+s-s1,使用离线做法

代码:


#include <bits/stdc++.h>
#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
#define lowbit(x) x&(-x)
const int N = 2000010;
int c[N];
void add(int x, int y) {
    for (; x < N; x += lowbit(x)) c[x] += y;
}
int ask(int x) {
    int res = 0;
    for (; x; x -= lowbit(x)) res += c[x];
    return res;
}
struct T {
    int  val, sum;
    map<int, int> mp;
} pro[N];
struct TT {
    int opt, a, b, c;
} query[N];
int lst[N];
void solve(int Case) {
    int n, m, q;
    vector<T> v;
    cin >> n >> m >> q;
    for (int i = 1; i <= q; i++) {
        int op;
        cin >> op;
        if (op == 1) {
            int l, r, x;
            cin >> l >> r >> x;
            query[i] = {1, l, r, x};
            continue;
        } else if (op == 2) {
            int a, b;
            cin >> a >> b;
            lst[a] = i;
            query[i] = {2, a, b, 0};
        } else if (op == 3) {
            int a, b;
            cin >> a >> b;
            int p = lst[a];
            pro[p].mp[b] = 0;
            query[i] = {3, a, b, 0};
        }
    }
    for (int i = 1; i <= q; i++) {
        auto [op, a, b, c] = query[i];
        if (op == 1) {
            add(a, c), add(b + 1, -c);
        } else if (op == 2) {

            pro[i].val = b;
            lst[a] = i;
        } else {
            int s = ask(b);
            int p = lst[a];
            
            int s1 = pro[p].mp[b];
            int x = pro[p].val;
            cout << x + s - s1 << nline;
        }
        auto &mp = pro[i].mp;
        for (auto &[x, v] : mp) {
            v = ask(x);
        }
    }

}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
//   for (cin>>_, Case = 1; Case <= _; Case++)
    solve(Case);

    return 0;
}
posted @ 2022-06-16 15:58  指引盗寇入太行  阅读(27)  评论(0编辑  收藏  举报