2019 ICPC Asia Yinchuan Regional

B. So Easy || 思维

行列之差,注意边界处理

#include <bits/stdc++.h>
using namespace std;

int a[1111][1111];

int main()
{
    int n;
    cin >> n;
    int idx, idy;
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= n; ++j)
        {
            scanf("%d", &a[i][j]);
            if(a[i][j] == -1)
            {
                idx = i;
                idy = j;
            }
        }
    }
    //cout << idx << ' ' << idy << endl;
    if(idx == n)
    {
        if(idy == n)
            cout << a[idx-1][idy] - a[idx-1][idy-1] + a[idx][idy-1] << endl;
        else cout << a[idx-1][idy] - a[idx-1][idy+1] + a[idx][idy+1] << endl;
    }
    else
    {
        if(idy == n)
            cout << a[idx][idy-1] - a[idx+1][idy-1] + a[idx+1][idy] << endl;
        else cout << a[idx][idy+1] - a[idx+1][idy+1] + a[idx+1][idy] << endl;
    }

}

G. Pot!! || 线段树

维护2、3、5、7四棵线段树,由于代码复用,所以在函数中添加int* tree和int* lazy

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;

int a[maxn], tr2[maxn<<2], tr3[maxn<<2], tr5[maxn<<2], tr7[maxn<<2], lz2[maxn<<2], lz3[maxn<<2], lz5[maxn<<2], lz7[maxn<<2];
void build(int* tree, int node, int l, int r)
{
    if(l == r)
    {
        tree[node] = a[l];
        return;
    }
    int mid = (l + r) / 2;
    build(tree, node * 2, l, mid);
    build(tree, node * 2 + 1, mid + 1, r);
    tree[node] = max(tree[node*2], tree[node*2+1]);
}

void push_down(int* tree, int* lazy, int node)
{
    if(lazy[node])
    {
        tree[2*node] += lazy[node];
        tree[2*node+1] += lazy[node];
        lazy[2*node] += lazy[node];
        lazy[2*node+1] += lazy[node];
        lazy[node] = 0;
    }
}

void update(int* tree, int* lazy, int node, int l, int r, int x, int y, int c)
{
    if(x <= l && y >= r)
    {
        tree[node] += c;
        lazy[node] += c;
        return;
    }

    push_down(tree, lazy, node);

    int mid = (l + r) / 2;
    if(x <= mid) update(tree, lazy, node * 2, l, mid, x, y, c);
    if(y > mid) update(tree, lazy, node * 2 + 1, mid + 1, r, x, y, c);
    tree[node] = max(tree[node*2], tree[node*2 + 1]);
}

int query(int* tree, int* lazy, int node, int l, int r, int x, int y)
{
    if(x <= l && y >= r) return tree[node];

    push_down(tree, lazy, node);
    int ans = 0; int mid = (l + r) / 2;
    if(x <= mid) ans = query(tree, lazy, node * 2, l, mid, x, y);
    if(y > mid) ans = max(ans, query(tree, lazy, node * 2 + 1, mid + 1, r, x, y));
    return ans;

}

int main()
{
    int n, q, x, y, w;
    cin >> n >> q;
    string s;
    //fill(a + 1, a + 1 + n, 1); 开始不是1!!!!! 是0!!!!!!
    build(tr2, 1, 1, n);
    build(tr3, 1, 1, n);
    build(tr5, 1, 1, n);
    build(tr7, 1, 1, n);
    while(q--)
    {
        cin >> s >> x >> y;
        if(s == "MULTIPLY")
        {
            cin >> w;
            if(w == 2) update(tr2, lz2, 1, 1, n, x, y, 1);
            else if(w == 3) update(tr3, lz3, 1, 1, n, x, y, 1);
            else if(w == 4) update(tr2, lz2, 1, 1, n, x, y, 2);
            else if(w == 5) update(tr5, lz5, 1, 1, n, x, y, 1);
            else if(w == 6)
            {
                update(tr3, lz3, 1, 1, n, x, y, 1);
                update(tr2, lz2, 1, 1, n, x, y, 1);
            }
            else if(w == 7) update(tr7, lz7, 1, 1, n, x, y, 1);
            else if(w == 8) update(tr2, lz2, 1, 1, n, x, y, 3);
            else if(w == 9) update(tr3, lz3, 1, 1, n, x, y, 2);
            else if(w == 10)
            {
                update(tr2, lz2, 1, 1, n, x, y, 1);
                update(tr5, lz5, 1, 1, n, x, y, 1);
            }
        }
        else
        {
            printf("ANSWER %d
", max({query(tr2, lz2, 1, 1, n, x, y), query(tr3, lz3, 1, 1, n, x, y), query(tr5, lz5, 1, 1, n, x, y), query(tr7, lz7, 1, 1, n, x, y)}));
            //printf("2: %d
", query(tr2, lz2, 1, 1, n, x, y));
            //printf("3: %d
", query(tr3, lz3, 1, 1, n, x, y));
            //printf("5: %d
", query(tr5, lz5, 1, 1, n, x, y));
            //printf("7: %d
", query(tr7, lz7, 1, 1, n, x, y));
        }
    }
}

F. Function! || 数学

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 998244353;

ll qpow(ll a, ll b)
{
    ll t = 1;
    for(; b; b >>= 1, a = a * a % mod)
        if(b & 1)  t = t * a % mod;
    return t;
}

ll cal(ll x)
{
    return (x % mod * ((x + 1) % mod) % mod * ((2 * x + 1) % mod) % mod) * qpow(6, mod - 2) % mod; // 相乘每个数都要先取模,因为ll * ll可能会爆ll

}

int main()
{
    ll n;
    cin >> n;
    int x = sqrt(n);
    ll sum = 0;
    for(int a = 2; a <= x; ++a)
    {
        ll tmp = a;
        ll cnt = 1;
        while(tmp <= n)
        {
            sum += min(tmp * (a - 1), n - tmp + 1) * cnt * a;
            //cout << sum << endl;
            sum %= mod;
            ++cnt;
            tmp *= a;
        }
        //cout << "tmp " << tmp << endl;
        //cout << a << endl;
        //cout << sum << endl;
    }
    //cout << sum << endl;
    //cout << (cal(n) - cal(x)) % mod << endl;
    sum -= cal(n) - cal(x);
    //cout << sum << endl;
    sum += 1LL * (n + 1) % mod * ((x + 1 + n) % mod) % mod * ((n - x) % mod) % mod * qpow(2, mod - 2) % mod;// 相乘每个数都要先取模,因为ll * ll可能会爆ll

cout << (sum % mod + mod) % mod << endl; // 防止sum为负数,且注意上一行求得的sum还未取模,先要取一次模
}
原文地址:https://www.cnblogs.com/Maxx-el/p/14059679.html