传送门

C Darkness I

这个题就是找出一种放最少几个黑块能全部变黑,我么可以沿着对角线放,先以最小的那一边的正方形用对角线的方法放完,然后再两隔一列放一个,但是要注意向上取整。

#include<bits/stdc++.h>

#define int long long
#define fi first
#define se second

using namespace std;

const int N = 100010;
const int M = 998244353;

int n, m;
int a[N];
int ans[N];

void solve() {
    cin >> n >> m;
    if (n > m)swap(n, m);
    int cnt = m - n;
    cout << n + (cnt + 1) / 2;
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int h_h;
    //cin >> h_h;
    h_h = 1;
    while (h_h--)solve();
    return 0;
}

F Inverse Manacher

这个题就是先初始化一个字符串为"&|a",然后从第三个开始,每次判断一下位置,偶数是放|,奇数是放字母,每次将回文串复制到右边并移动指针,因为题目保证一定有解,但是放|的时候回文串的长度为1那么左右两边的字母会不一样,而且数组要注意开两倍。

#include<bits/stdc++.h>

#define int long long
#define fi first
#define se second

using namespace std;

const int N = 2000010;
const int M = 998244353;

int n, m;
int a[N];

void solve() {
    cin >> n;
    for (int i = 1; i <= 2 * n + 2; i++)cin >> a[i];
    string sans = " &|a";
    for (int i = 4; i <= 2 * n + 2; i++) {
        if (i % 2 == 0)sans += '|';
        else {
            if (a[i - 1] == 1) {
                if (sans[i - 2] == 'a')sans += 'b';
                else sans += 'a';
            } else {
                if (sans[i - 2] == 'a')sans += 'a';
                else sans += 'b';
            }
        }
        if (a[i] == 1)continue;
        int pos = i - a[i] + 1;
        string s = sans.substr(pos, a[i] - 1);
        reverse(s.begin(), s.end());
        sans += s;
        i += a[i] - 1;
    }
    string ans;
    for (auto i: sans) {
        if (i == '&' || i == '|' || i == ' ')continue;
        ans += i;
    }
    cout << ans << endl;
    if (sans.size() > n + 1) {
        while (sans.size() != n + 1)sans.pop_back();
    }
}
/*5
1 1 2 1 4 1 2 3 4 3 2 1
& | a | b | a | a | a |
 */
int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int h_h;
    //cin >> h_h;
    h_h = 1;
    while (h_h--)solve();
    return 0;
}

H Binary Craziness

这个题如果暴力枚举会超时,但是我们可以把每个点的度求出来,并用map存下来每个度出现的次数,因为两个数计算,这两个数相同的次数可能会出现很多次,如果遇见度数相同的就按照n*(n+1)/2来计算它的贡献即可,而如果两个数不相同对答案的贡献是两个数出现的次数乘积,但只能计算一次,不能重复计算。

#include<bits/stdc++.h>

#define int long long
#define fi first
#define se second

using namespace std;

const int N = 1000010;
const int M = 998244353;

int n, m;
int dg[N];
map<int,int> mp;
map<pair<int,int>,int> mp1;

void solve() {
    cin >> n >> m;
    while (m--) {
        int a, b;
        cin >> a >> b;
        dg[a]++;
        dg[b]++;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)mp[dg[i]]++;
    //cout << endl;
    //for (auto i: mp)cout << i.first << endl;
    for (auto i: mp) {
        for (auto j: mp) {
            int cnt = 0;
            auto a = i.fi;
            auto b = j.fi;
            if(a>b)swap(a,b);
            if (a == b) cnt = (i.se + 1) * i.se / 2;
            else if (!mp1.count({a, b}))cnt = i.se * j.se, mp1[{a, b}] = 1;
            ans += (i.fi ^ j.fi) * (i.fi | j.fi) * (i.fi & j.fi) * cnt;
            ans %= M;
        }
    }
    cout << ans << endl;
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int h_h;
    //cin >> h_h;
    h_h=1;
    while (h_h--)solve();
    return 0;
}

J Expansion

读了好才读懂题目,意思就是先把数字处理前缀和,最开始是在第一个单元格,在哪个单元格资源的增长就是这个单元格的值,呀保证在走完全部的单元格的过程中,资源总是非负,然后无论然后都不能保证输出-1,如果第一个和最后一个为负数则肯定不能满足,否则如果是正数就直接走,然后是负数,走完这个各自以后目前的资源为负,那要在前面值为正的单元停留增长资源,直到能够走过这个为负的单元格,题目要求最少,则我们就找前面资源增长最大的即可。

#include<bits/stdc++.h>

#define int long long
#define fi first
#define se second

using namespace std;

const int N = 100010;
const int M = 998244353;

int n, m;
int a[N], s[N];

void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++)cin >> a[i], s[i] = s[i - 1] + a[i];
    if (s[1] < 0 || s[n] < 0) {
        cout << -1 << endl;
        return;
    }
    int ans = 0, mx = 0, cnt = 0;
    for (int i = 1; i <= n; i++) {
        cnt += s[i];
        ans++;
        mx = max(mx,s[i]);
        if (cnt < 0) {
            if(mx==0){
                cout<<-1<<endl;
                return ;
            }
            ans += (abs(cnt) + mx - 1) / mx;
            cnt += (abs(cnt) + mx - 1) / mx * mx;
        }
    }
    cout << ans << endl;
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int h_h;
    //cin >> h_h;
    h_h = 1;
    while (h_h--)solve();
    return 0;
}

K Dice Game

是一个概率问题,问有n个人玩m个面的色子,问在第一人点数确定的情况下,它的点数为1,2,3,...m的情况下的输的概率,相同约等于无效,而这个问题的答案就是q=ksm(m-i,n),p=ksm(m-1,n),按照题目写个快速幂输出即可。

#include<bits/stdc++.h>

#define int long long
#define fi first
#define se second

using namespace std;

const int N = 100010;
const int M = 998244353;

int n, m;
int a[N];
int ans[N];

int ksm(int x, int y) {
    int res = 1;
    while (y) {
        if (y & 1)res = res * x % M;
        x = x * x % M;
        y >>= 1;
    }
    return res % M;
}

void solve() {
    cin >> n >> m;
    ans[1] = 1;
    ans[m] = 0;
    for (int i = 2; i <= m; i++) {
        int q = ksm(m - i, n) % M;
        int p = ksm(m - 1, n) % M;
        ans[i] = q % M * ksm(p, M - 2) % M;
    }
    for (int i = 1; i <= m; i++)cout << ans[i] << ' ';
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int h_h;
    //cin >> h_h;
    h_h = 1;
    while (h_h--)solve();
    return 0;
}

M Different Billing

签到题,而迷局b或c都可以

#include<bits/stdc++.h>

#define int long long
#define fi first
#define se second

using namespace std;

const int N = 100010;
const int M = 998244353;

int n, m;
int a[N];
int ans[N];

int ksm(int x, int y) {
    int res = 1;
    while (y) {
        if (y & 1)res = res * x % M;
        x = x * x % M;
        y >>= 1;
    }
    return res % M;
}

void solve() {
    cin >> n >> m;
    for (int i = 0; i <= n; i++) {
        int cnt = m - 1000 * i;
        if (cnt % 2500 == 0 && i + cnt / 2500 <= n) {
            cout << n - i - cnt / 2500 << ' ' << i << ' ' << cnt / 2500 << endl;
            return;
        }
    }
    cout << -1 << endl;
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int h_h;
    //cin >> h_h;
    h_h = 1;
    while (h_h--)solve();
    return 0;
}