首页 > 其他分享 >「解题报告」AGC012E Camel and Oases

「解题报告」AGC012E Camel and Oases

时间:2023-05-19 21:04:10浏览次数:45  
标签:suf AGC012E now Camel int 后缀 MAXN Oases 时刻

好久之前模拟赛就考过的题,今天才写)

首先发现我们跳跃的次数只有 \(\log V\) 次,我们设跳了 \(i\) 次后的时刻为第 \(i\) 时刻,且最后一个时刻为 \(t\)。发现每一时刻,我们能够到达的绿洲形成了若干个连续段。不难发现,当时刻 \(0\) 的时候连续段数量大于 \(t + 1\) 时一定全部都无法到达。而对于这每一个连续段,答案一定相等。

那么我们只需要对 \(O(\log V)\) 个位置找出答案即可。考虑如何求答案。

首先发现我们要到达的就是一个前缀加一个后缀,而每一时刻要不然在前缀要不然在后缀,那么我们可以设 DP \(pre_S, suf_S\) 表示如果在 \(S\) 这个时刻集合内都在前缀 / 后缀,那么能覆盖的最长前缀 / 最长后缀是多少。直接转移即可。注意到虽然我们不一定是按顺序从左往右访问,但是由于时刻集合的转移本身就没有顺序,所以是可以覆盖到所有情况的。

总时间复杂度 \(O((n + V) \log V)\)。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200005;
int n, v, t;
int x[MAXN];
int L[22][MAXN], R[22][MAXN];
int pre[1 << 19], suf[1 << 19];
void chkmax(int &a, int b) { a = max(a, b); }
void chkmin(int &a, int b) { a = min(a, b); }
int main() {
    scanf("%d%d", &n, &v);
    t = __lg(v) + 1;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &x[i]);
    }
    for (int j = 0; j <= t; j++) {
        L[j][1] = 1;
        for (int i = 2; i <= n; i++) {
            if (x[i] - x[i - 1] <= (v >> j)) L[j][i] = L[j][i - 1];
            else L[j][i] = i;
        }
        R[j][n] = n;
        for (int i = n - 1; i >= 1; i--) {
            if (x[i + 1] - x[i] <= (v >> j)) R[j][i] = R[j][i + 1];
            else R[j][i] = i;
        }
    }
    memset(suf, 0x3f, sizeof suf);
    suf[0] = n + 1;
    int cnt = 0, now = R[0][1];
    while (now < n) now = R[0][now + 1], cnt++;
    if (cnt > t) {
        for (int i = 1; i <= n; i++) {
            printf("Impossible\n");
        }
        return 0;
    }
    for (int s = 0; s < (1 << t); s++) {
        for (int i = 1; i <= t; i++) if (!(s >> (i - 1) & 1)) {
            chkmax(pre[s | 1 << (i - 1)], R[i][min(pre[s] + 1, n)]);
            chkmin(suf[s | 1 << (i - 1)], L[i][max(suf[s] - 1, 1)]);
        }
    }
    int S = (1 << t) - 1;
    for (int l = 1, r; l <= n; l = r + 1) {
        r = R[0][l];
        bool flag = false;
        for (int s = 0; s < (1 << t); s++) {
            if (pre[s] >= l - 1 && suf[S ^ s] <= r + 1) {
                flag = true;
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (flag) printf("Possible\n");
            else printf("Impossible\n");
        }
    }
    return 0;
}

标签:suf,AGC012E,now,Camel,int,后缀,MAXN,Oases,时刻
From: https://www.cnblogs.com/apjifengc/p/17416254.html

相关文章

  • AutoGPT、AgentGPT、BabyAGI、HuggingGPT、CAMEL:各种基于GPT-4自治系统总结
    ChatGPT和LLM技术的出现使得这些最先进的语言模型席卷了世界,不仅是AI的开发人员,爱好者和一些组织也在研究探索集成和构建这些模型的创新方法。各种平台如雨后春笋般涌现,集成并促进新应用程序的开发。AutoGPT的火爆让我们看到越来越多的自主任务和代理利用了GPT-4的API。这些发展......
  • Camel详解
     ApacheCamel测试指南https://www.cnblogs.com/d1012181765/p/15338830.html Camel中的转换:如何进行https://www.cnblogs.com/d1012181765/p/15339030.html ......
  • Apache Camel Support
    Spring集成提供了一个API和配置,用于与在同一应用程序上下文中声明的 ApacheCamel 端点进行通信。您需要将此依赖项包含在项目中:<dependency><groupId>org.springf......
  • [Typescript] 99. Hard - CamelCase
    Implement CamelCase<T> whichconverts snake_case stringto camelCase.ForexampletypecamelCase1=CamelCase<'hello_world_with_types'>//expectedtobe......
  • 【ARC105C】Camels and Bridge 题解
    题意给定\(n\)只骆驼和每条骆驼的重量\(a_i\)。这些骆驼要通过一条路,这条路被分为\(m\)个部分,每个部分的长度为\(l_i\),限重为\(v_i\)。同时经过这部分的骆驼的重......