【洛谷】【LGR-167-Div.2】复旦勰码 12 月月赛 I 做题记录

A. 「RiOI-03」water problem

比赛一开始犯蠢了,直接考虑打表,不过需要注意的是除了把一个分成若干个小正方形的这个分法以外,还有一种分法是可以让满足 \(n\geq 4\)\(n \equiv 0(\mod 2)\) 满足条件。

最后得到的结论就是 \(2,3,5\) 是不可以的,其余都是可以的。

B. 「RiOI-03」匀速相遇

根据关系速度关系列出方程,可以发现如果两个点要能够相遇,必须要满足:

\[a[i]\times i=b[j] \times j \]

特判一下 0,然后用 umap 存储一下就可以了。

C. 「RiOI-03」3-2

可以很容易得到一个结论就是答案一定是 \(2^k-1\) 的形式。

再观察一下 \(n = 3\) 的形式,那么就可以找到规律其实就找到当前联通块最长的某个横行,然后 \(k\) 就等于这个横行的长度。

并且这个横行既可以在联通块的最上方也可以在最下方,所以取往上找和往下找的最大值即可。

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

const int P = 998244353;

int power(int x, i64 y) {
    int r = 1;
    for (; y; y /= 2, x = 1ll * x * x % P) {
        if (y & 1) r = 1ll * r * x % P;
    }
    return r;
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    i64 n;
    int q;
    cin >> n >> q;

    while (q--) {
        i64 x, y;
        cin >> x >> y;

        if (y >= 60) {
            int ans = power(2, n) - 1;
            if (ans < 0) {
                ans += P;
            }
            cout << ans << "\n";
        } else {
            int up = min(n, 60ll);
            
            auto count = [&](i64 x) {
                int cnt = 0;
                for (int i = y; i >= 0; i--) {
                    if ((x >> i & 1) == (x >> y & 1)) cnt++;
                    else break;
                }
                for (int i = y + 1; i < up; i++) {
                    if ((x >> i & 1) == (x >> y & 1)) cnt++;
                    else break;
                }
                return cnt;
            };

            int mx = 0;
            {
                i64 val = x;
                for (int i = y; i >= 0; i--) {
                    if ((val >> y & 1) == ((val + (1ll << i)) >> y & 1)) {
                        val += 1ll << i;
                    }
                }
                mx = max(mx, count(val));
            }

            {
                i64 val = x;
                for (int i = y; i >= 0; i--) {
                    if (val >= (1ll << i) && (val >> y & 1) == ((val - (1ll << i)) >> y & 1)) {
                        val -= 1ll << i;
                    }
                }
                mx = max(mx, count(val));
            }

            int ans = power(2, mx) - 1;
            if (ans < 0) ans += P;
            cout << ans << "\n";
        }
    }
}

D. 「RiOI-03」Just a Q. (Easy ver.)

待补

E. 「RiOI-03」网格

待补

posted @ 2023-12-10 03:37  mulberror  阅读(144)  评论(0)    收藏  举报