首页 > 其他分享 >CF1977E 题解

CF1977E 题解

时间:2024-09-20 18:50:25浏览次数:11  
标签:int 题解 back else ask CF1977E push stk

根据 Dilworth 定理,该图能被两条互不相交的链覆盖。

从小到大加点。我们现在需要维护两个栈,每个栈维护每条链的点。

若两个栈头没有连边,那么对于新加入的点,一定可以放到其中一个栈。

现在唯一的问题是,新加入的点可能可以放入两个栈。

我们可以再开一个栈三,用来维护以上述点为头的链。

对于一个新加入的点,分以下情况:

  • 若栈三为空。分别与前两个栈的栈头询问。分情况加入三个栈即可。

  • 若栈三不为空。先询问是否与栈三的栈头相连。若相连,则加入栈三。否则,加入前两个栈头与其相连的栈中(若有两个,任选一个即可)。然后将栈三的所有元素加入到与其相反的栈中。

容易发现,这样构造一定能使得前两个栈的栈头不相连。对于每个点,最多询问 \(2\) 次。所以总的询问次数不多于 \(2n\)。

#include <bits/stdc++.h>

using i64 = long long;

int ask(int a, int b) {
    std::cout << "? " << a + 1 << " " << b + 1 << std::endl;
    std::string s;
    std::cin >> s;
    return s == "YES";
}

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> c(n);
    std::vector<int> stk[3];
    stk[0].push_back(0);
    for (int i = 1; i < n; i ++ ) {
        if (stk[1].empty()) {
            if (ask(stk[0].back(), i)) {
                stk[0].push_back(i);
            } else {
                stk[1].push_back(i);
            }
        } else {
            if (stk[2].empty()) {
                int x = ask(stk[0].back(), i);
                int y = ask(stk[1].back(), i);
                if (!x) {
                    stk[1].push_back(i);
                } else if (!y) {
                    stk[0].push_back(i);
                } else {
                    stk[2].push_back(i);
                }
            } else {
                if (ask(stk[2].back(), i)) {
                    stk[2].push_back(i);
                } else if (ask(stk[0].back(), i)) {
                    stk[0].push_back(i);
                    for (auto j : stk[2]) {
                        stk[1].push_back(j);
                    }
                    stk[2].clear();
                } else {
                    stk[1].push_back(i);
                    for (auto j : stk[2]) {
                        stk[0].push_back(j);
                    }
                    stk[2].clear();
                }
            }
        }
    }

    for (auto i : stk[1]) {
        c[i] = 1;
    }

    std::cout << "!";
    for (int i = 0; i < n; i ++ ) {
        std::cout << " " << c[i];
    }
    std::cout << std::endl;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t;
    std::cin >> t;

    while (t -- ) {
        solve();
    }

    return 0;
}

标签:int,题解,back,else,ask,CF1977E,push,stk
From: https://www.cnblogs.com/hcywoi/p/18423061

相关文章

  • 【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【模拟】2024E-转骰子
    可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明解题思路构建长度为6的数组表......
  • 题解:洛谷P9934 [NFLSPC #6] 绝不能忘记的事……
    题目链接:洛谷P9934[NFLSPC#6]绝不能忘记的事……我hatelove大力分讨。这道题先分三种大情况:N在左边,N在中间,N在右边。声明:以下分类讨论中,a,b,c,d均为记住的字符串。记录操作N在左边当复制串形如Nab,可以用map<string,int>记录。当复制串形如NaH,那么......
  • 【问题解决】Web在线办公系统-数据爬取结果乱码
    问题描述在【热门电影】模块,通过jsoup爬虫并解析网页数据时,执行代码,出现“中文乱码”问题。解决方法由于网页自带的编码方式与后端开发中jsoup解析的编码方式不匹配,需要修改后端解析网页的编码方式。//设置爬取网页的地址Stringurl="https://movie.douban.com/......
  • Gradio离线部署到内网,资源加载失败问题(Gradio离线部署问题解决方法)
    问题描述Gradio作为一个快速构建一个演示或Web应用的开源Python包,被广泛使用,最近在用这个包进行AI应用构建,打包部署到内网Docker的时候发现有些资源无法使用。网页加载不出来。即使加载出来了也是没有样式无法点击的。一般出现这个问题的多半是低版本的gradio,高版本中已经解决......
  • CF1526F Median Queries 题解
    Description本题是一道交互题。给定\(n\),你需要猜测一个长度为\(n\)的排列\(p\)(即\(p\)包含所有\(1\)到\(n\)的整数各一次)。已知\(p\)满足\(p_1<p_2\)。当然,你可以进行询问,每次询问你需要给定三个互不相同的整数\(a,b,c\),交互器会返回\(|p_a-p_b|,|p_b-p_c|,|p_......
  • P9705 「TFOI R1」Unknown Graph题解
    思路题目给出了每个点的初度和入度,由于图是无重边无自环的有向图。要求满足限制的图有多少条边与建图方案。我们可以考虑使用网络流中的最大流。我们知道这是一道网络流后,题目的难点就转移到网络流的建模以及输出方案的办法。网络流的建模:题目所给的条件没有源点汇点并指出......
  • P5979 [PA2014] Druzyny 题解
    对于一个固定的右端点\(r\),左端点\(l\)合法当且仅当\(\max(d_l,d_{l+1},\dotsd_r)\ler-l+1\le\min(c_l,c_{l+1},\dots,c_r)\)。容易得到一个很朴素的dp:记\(f_i\)表示前\(i\)个位置可以分成的组的数目的最大值,\(g_i\)表示有多少种分组方案能达到最大值,直接枚举左端点......
  • CF2004G 题解
    题意定义关于数字串\(s\)的函数\(f(s)\)表示将\(t\)切分为\(m\)段,要求\(m\)是偶数,假设这些字符串分别为\(t_1,t_2,\ldots,t_m\),有\(s=t_1+t_2+\ldots+t_m\)。定义\(A^x\)表示\(\underbrace{AA\ldotsAA}_{x~\text{times}}\),求一种划分方式,使得\(t_2^......
  • P1108 低价购买 题解
    这题在求最长下降子序列的基础上加了一个求方案数的要求,这就让这道题目变难了很多。我们考虑我们在求最长下降子序列的时候,总是从这一位,要么重新开始计数,要么只和前面的有关,所以前面的信息完全丢失了,无法判断有多少方案,所以我们就要针对前面的方案数设计一个dp来统计。可以称之......
  • 题解:CF1906F Maximize The Value
    可以在cnblog中阅读。见这种题比较少,写篇题解加深印象。如果直接上数据结构维护数组,似乎没有好的办法处理操作序列的一个子段。那不妨转变思路,对操作序列上数据结构维护。假设顺序进行每个修改操作,我们用时间表示修改操作的编号,位置表示数组的下标,则常见的维护序列的数据结构......