【21.10.24】The 15th Chinese Northeast Collegiate Programming Contest题解

A. Matrix(组合数+数学)

#include <bits/stdc++.h>
using namespace std;
#define mod 998244353
ll fac[100010], inv[100010];
const int maxn = 3e7 + 10;
ll mul[maxn];
 
ll kasumi (ll a, ll b) {
    ll ans = 1;
    while (b) {
        if (b & 1) {
            ans = ans * a % mod;
        }
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}
 
void zuheshu() {
    fac[0] = 1;
    for (int i = 1; i <= 100000; i++) {
        fac[i] = fac[i - 1] * i % mod;
    }
    inv[100000] = kasumi (fac[100000], mod - 2);
    for (int i = 99999; i >= 0; i--) {
        inv[i] = inv[i + 1] * (i + 1) % mod;
    }
}
 
void jiechen() {
    mul[0] = 1;
    mul[1] = 1;
    for (int i = 2; i <= maxn - 10; i++) {
        mul[i] = mul[i - 1] * i % mod;
    }
}
 
ll get_c (ll x, ll y) {
    return fac[x] * inv[y] % mod * inv[x - y] % mod;
}
 
int main() {
    int T;
    scanf ("%d", &T);
    zuheshu();
    jiechen();
    while (T--) {
        ll n;
        scanf ("%lld", &n);
        ll ans = 0;
        ll p = mul[n];
        ll q = mul[n * n - n];
        for (int i = 1; i <= n; i++) {
            ans += n * get_c (n * n - i, n - 1) * p * q;
        }
        cout << ans << endl;
    }
}

B.Cypher(大模拟)

有空填坑

C.Vertex Deletion(简单树形DP) 

#include <btis/stdc++.h>
using namespace std;
#define mod 998244353
const int maxn = 2e5 + 50;
 
ll dp[maxn][5];
 
vector<int>G[maxn];
 
void dfs (int u, int father) {
    dp[u][0] = 1;
    dp[u][1] = 1;
    dp[u][2] = 1;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (v == father) {
            continue;
        } else {
            dfs (v, u);
            dp[u][0] = (dp[u][0] % mod * (dp[v][0] + dp[v][2]) % mod) % mod;
            dp[u][1] = dp[u][1] * dp[v][0] % mod;
            dp[u][2] = (dp[u][2] * (dp[v][0] + dp[v][1] + dp[v][2]) % mod) % mod;
        }
    }
    dp[u][2] = (dp[u][2] - dp[u][1] + mod) % mod;
}
 
int main() {
    int T;
    scanf ("%d", &T);
    while (T--) {
        int n;
        scanf ("%d", &n);
        for (int i = 1; i <= n - 1; i++) {
            int u, v;
            scanf ("%d%d", &u, &v);
            G[u].push_back (v);
            G[v].push_back (u);
        }
        dfs (1, 0);
        cout << (dp[1][0] + dp[1][2]) % mod << endl;
        for (int i = 0; i <= n; i++) {
            G[i].clear();
        }
    }
}

D.Lowbit(线段树区间求和) 

注意:

lowbit不能取模,会改变下一轮lowbit的答案

#include <bits/stdc++.h>
#define ll long long
#define lson root << 1
#define rson root << 1 | 1
#define lowbit(x) ((x) & (-x))
using namespace std;
const int N = 1e5 + 7;
const int mod = 998244353;

struct tree {
    int l, r;
    ll sum;
    int cnt;
    ll lazy;
    int fsum;
} tr[N << 2];

int n;
ll a[N];

void push_up(int root) {
    tr[root].sum = (tr[lson].sum + tr[rson].sum) % mod;
    tr[root].fsum = tr[lson].fsum + tr[rson].fsum;
}

void push_down(int root) {
    if (tr[root].lazy != 1) {
        tr[lson].sum = tr[lson].sum * tr[root].lazy % mod;
        tr[rson].sum = tr[rson].sum * tr[root].lazy % mod;
        tr[lson].lazy *= tr[root].lazy;
        tr[rson].lazy *= tr[root].lazy;
        tr[lson].lazy %= mod;
        tr[rson].lazy %= mod;
        tr[root].lazy = 1;
    }
}

void build(int root, int l, int r) {
    tr[root].l = l;
    tr[root].r = r;
    tr[root].lazy = 1;
    tr[root].fsum = 0;
    if (l == r) {
        tr[root].sum = a[l] % mod;
        ll x = a[l];
        int tot = 0;
        bool flag = 0;
        while (x) {
            if (x & 1) {
                flag = 1;
            } else {
                if (flag) {
                    tot++;
                }
            }
            x >>= 1;
        }
        tr[root].cnt = tot + 1;
        return;
    }
    int mid = (l + r) >> 1;
    build(lson, l, mid);
    build(rson, mid + 1, r);
    push_up(root);
}

void update(int root, int l, int r) {
    if (l <= tr[root].l && tr[root].r <= r) {
        if (tr[root].fsum == tr[root].r - tr[root].l + 1) {
            tr[root].sum = tr[root].sum * 2 % mod;
            tr[root].lazy *= 2;
            tr[root].lazy %= mod;
            return;
        }
        if (tr[root].l == tr[root].r) {
            tr[root].sum += lowbit(tr[root].sum);
            //tr[root].sum %= mod;
            if (tr[root].cnt) {
                tr[root].cnt--;
            }
            if (tr[root].cnt == 0) {
                tr[root].fsum = 1;
            }
            return;
        }
    }
    push_down(root);
    int mid = (tr[root].l + tr[root].r) >> 1;
    if (r <= mid) {
        update(lson, l, r);
    } else {
        if (l > mid) {
            update(rson, l, r);
        } else {
            update(lson, l, mid);
            update(rson, mid + 1, r);
        }
    }
    push_up(root);
}

ll query(int root, int l, int r) {
    if (l <= tr[root].l && tr[root].r <= r) {
        return tr[root].sum % mod;
    }
    push_down(root);
    int mid = (tr[root].l + tr[root].r) >> 1;
    if (r <= mid) {
        return query(lson, l, r) % mod;
    } else if (mid < l) {
        return query(rson, l, r) % mod;
    } else {
        return (query(lson, l, mid) % mod + query(rson, mid + 1, r) % mod) % mod;
    }
}
int main() {
    int T = 1;
    scanf("%d", &T);
    while (T--) {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &a[i]);
        }
        build(1, 1, n);
        int q;
        scanf("%d", &q);
        while (q--) {
            int op, l, r;
            scanf("%d%d%d", &op, &l, &r);
            if (l > r) swap(l, r);
            if (op == 1) {
                update(1, l, r);
            } else {
                printf("%lld\n", query(1, l, r));
            }
        }
    }
    //system("pause");
    return 0;
}

E.Easy Math Problem(简单思维构造)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main() {
    int T;
    scanf ("%d", &T);
    while (T--) {
        ll p;
        scanf ("%d", &p);
        ll ans = p * 6;
        cout << ans << " " << 3 << endl;
        cout << ans / 2 << " " << ans / 3 << " " << ans / 6 << endl;
    }
}

F. Permutation(数据结构?)

G. Ball(DP吧)

H. Loneliness(构造,有空补)

 I. Takeaway(签到题)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int T;
int p[7] = {7, 27, 41, 49, 63, 78, 108};
int main() {
    scanf("%d", &T);
    while (T--) {
        int n;
        scanf("%d", &n);
        int sum = 0;
        for (int i = 0; i < n; i++) {
            int x;
            scanf("%d", &x);
            sum += p[x - 1];
        }
        if (sum >= 120) {
            sum -= 50;
        } else if (sum >= 89) {
            sum -= 30;
        } else if (sum >= 69) {
            sum -= 15;
        }
        printf("%d\n", sum);
    }
    return 0;
}

J. Transform(几何结论)

#include <bits/stdc++.h>
#define pi acos(-1.0)
using namespace std;

int main() {
    int T;
    scanf ("%d", &T);
    while (T--) {
        double A, B, C, x, y, z, r;
        scanf ("%lf%lf%lf%lf%lf%lf%lf", &A, &B, &C, &x, &y, &z, &r);
        double len = sqrt (A * A + B * B + C * C);
        double vx = A / len;
        double vy = B / len;
        double vz = C / len;
        double x1 = (vx * vx * (1 - cos (r / 180 * pi) ) + cos (r / 180 * pi) ) * x + (vx * vy * (1 - cos (r / 180 * pi) ) - vz * sin (r / 180 * pi) ) * y + (vx * vz * (1 - cos (r / 180 * pi) ) + vy * sin (r / 180 * pi) ) * z;
        double y1 = (vx * vy * (1 - cos (r / 180 * pi) ) + vz * sin (r / 180 * pi) ) * x + (vy * vy * (1 - cos (r / 180 * pi) ) + cos (r / 180 * pi) ) * y + (vy * vz * (1 - cos (r / 180 * pi) ) - vx * sin (r / 180 * pi) ) * z;
        double z1 = (vx * vz * (1 - cos (r / 180 * pi) ) - vy * sin (r / 180 * pi) ) * x + (vy * vz * (1 - cos (r / 180 * pi) ) + vx * sin (r / 180 * pi) ) * y + (vz * vz * (1 - cos (r / 180 * pi) ) + cos (r / 180 * pi) ) * z;
        r = -r;
        double x11 = (vx * vx * (1 - cos (r / 180 * pi) ) + cos (r / 180 * pi) ) * x + (vx * vy * (1 - cos (r / 180 * pi) ) - vz * sin (r / 180 * pi) ) * y + (vx * vz * (1 - cos (r / 180 * pi) ) + vy * sin (r / 180 * pi) ) * z;
        double y11 = (vx * vy * (1 - cos (r / 180 * pi) ) + vz * sin (r / 180 * pi) ) * x + (vy * vy * (1 - cos (r / 180 * pi) ) + cos (r / 180 * pi) ) * y + (vy * vz * (1 - cos (r / 180 * pi) ) - vx * sin (r / 180 * pi) ) * z;
        double z11 = (vx * vz * (1 - cos (r / 180 * pi) ) - vy * sin (r / 180 * pi) ) * x + (vy * vz * (1 - cos (r / 180 * pi) ) + vx * sin (r / 180 * pi) ) * y + (vz * vz * (1 - cos (r / 180 * pi) ) + cos (r / 180 * pi) ) * z;
        if (z11 > z1) {
            cout << fixed << setprecision (10) << x11 << " ";
            cout << fixed << setprecision (10) << y11 << " ";
            cout << fixed << setprecision (10) << z11 << endl;
        } else {
            cout << fixed << setprecision (10) << x1 << " ";
            cout << fixed << setprecision (10) << y1 << " ";
            cout << fixed << setprecision (10) << z1 << endl;
        }
    }
}

K. City(并查集)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 3;
struct node {
    int x;
    int y;
    ll k;
}a[N];
bool cmp1(node a, node b) {
    return a.k > b.k;
}
struct que{
    ll x;
    int id;
}p[N];
bool cmp2(que a, que b) {
    return a.x > b.x;
}
int fa[N];
int get(int x) {
    if (x == fa[x]) return x;
    return fa[x] = get(fa[x]);
}
ll ans[N];
ll num[N];
int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, m, q;
        scanf("%d%d%d", &n, &m, &q);
        for (int i = 1; i <= n; i++) {
            fa[i] = i;
            num[i] = 1ll;
        }
        for (int i = 1; i <= m; i++) scanf("%d%d%lld", &a[i].x, &a[i].y, &a[i].k);
        for (int i = 1; i <= q; i++) {
            scanf("%lld", &p[i].x);
            p[i].id = i;
        }
        sort(a + 1, a + 1 + m, cmp1);
        sort(p + 1, p + 1 + q, cmp2);
        int j = 1;
        ll sum = 0;
        for (int i = 1; i <= q; i++) {
            ll t = p[i].x;
            while (j <= m && a[j].k >= t) {
                int xx = get(a[j].x), yy = get(a[j].y);
                if (xx != yy) {
                    sum += 1ll * num[xx] * num[yy];
                    fa[xx] = yy;
                    num[yy] += num[xx];
                }
                j++;
            }
            ans[p[i].id] = sum;
        }
        for (int i = 1; i <= q; i++) {
            printf("%lld\n", ans[i]);
        }
    }
    return 0;
}

L. k-th Smallest Common Substring(难题)

M. Master of Shuangpin(模拟)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
map<string, char> m;
void init() {
    m["q"] = 'q';
    m["iu"] = 'q';
    m["w"] = 'w';
    m["ei"] = 'w';
    m["e"] = 'e';
    m["r"] = 'r';
    m["uan"] = 'r';
    m["t"] = 't';
    m["ue"] = 't';
    m["y"] = 'y';
    m["un"] = 'y';
    m["u"] = 'u';
    m["sh"] = 'u';
    m["i"] = 'i';
    m["ch"] = 'i';
    m["o"] = 'o';
    m["uo"] = 'o';
    m["p"] = 'p';
    m["ie"] = 'p';
    m["a"] = 'a';
    m["s"]='s';
    m["ong"]='s';
    m["iong"]='s';
    m["d"]='d';
    m["ai"]='d';
    m["f"]='f';
    m["en"]='f';
    m["g"]='g';
    m["eng"]='g';
    m["h"] = 'h';
    m["ang"] = 'h';
    m["j"] = 'j';
    m["an"] = 'j';
    m["k"] = 'k';
    m["uai"] = 'k';
    m["ing"] = 'k';
    m["l"] = 'l';
    m["uang"] = 'l';
    m["iang"] = 'l';
    m["z"] = 'z';
    m["ou"] = 'z';
    m["x"] = 'x';
    m["ia"] = 'x';
    m["ua"] = 'x';
    m["c"] = 'c';
    m["ao"] = 'c';
    m["v"] = 'v';
    m["zh"] = 'v';
    m["ui"] = 'v';
    m["b"] = 'b';
    m["in"] = 'b';
    m["n"] = 'n';
    m["iao"] = 'n';
    m["m"] = 'm';
    m["ian"] = 'm';
}
int main()
{
    init();
    string s;
    while (getline(cin, s)) {
        string t = "";
        s += '\n';
        for (int i = 0; i < s.length(); i++) {
            string ans = "";
            string tt = "";
            if (s[i] >= 'a' && s[i] <= 'z') {
                t += s[i];
            } else {
                if (t.length() == 2) {
                    cout << t << s[i];
                } else if (t.length() == 1) {
                    cout << t << t << s[i];
                } else {
                    if (t[1] == 'h' && (t[0] == 'c' || t[0] == 's' || t[0] == 'z')) {
                        tt = t[0];
                        tt += t[1];
                        ans = m[tt];
                        tt = t.substr(2);
                        ans += m[tt];
                    } else if (m[t]) {
                        cout << t[0] << m[t] << s[i];
                    } else {
                        tt = t[0];
                        ans = m[tt];
                        tt = t.substr(1);
                        ans += m[tt];
                    }
                    cout << ans << s[i];
                }
                t = "";
            }
        }
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值