首页 > 其他分享 >CF1372F Omkar and Modes 题解

CF1372F Omkar and Modes 题解

时间:2024-02-22 20:23:12浏览次数:23  
标签:return Modes rs int 题解 mid solve ls CF1372F

来个乱搞。

思路

考虑分治。

对于最裸的暴力。

我们可以调用 solve(l, r) 进行查询。

假如这个区间的众数的出现次数是区间长度,那么可以直接退出,否则我们可以继续分治。

我们把这个暴力进行加工一下。

我们知道 \(l\sim r\) 的区间众数后。

  1. 查询 \(l\sim mid\) 的区间众数,若完全与 \(l\sim r\) 一样,那么可以继续分治下去。

  2. 若仅有出现次数不一样,那么意味着我们已经知道了这个数的出现位置,可以直接构造答案,从两侧继续分治。

  3. 若都不一样,我们再查询 \(mid\sim r\) 的区间众数,可以仿照第一条第二条继续构造。

感觉是一个比较粗糙的做法,但又好像比较难卡。

这个做法的上下界我也不会算,如果有人可以 Hack 也比较正常。

Code

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
// #define int long long
#define mp(x, y) make_pair(x, y)
#define eb(...) emplace_back(__VA_ARGS__)
#define fro(i, x, y) for(int i = (x); i <= (y); i++)
#define pre(i, x, y) for(int i = (x); i >= (y); i--)
inline void JYFILE19();

typedef long long i64;
typedef pair<int, int> PII;

bool ST;
const int N = 1e6 + 10;
const int mod = 998244353;

int n, m, a[N];
map<PII, PII> mp;

inline PII ask(int l, int r) {
  if(mp.count({l, r})) {
    return mp[{l, r}];
  }
  cout << "? " << l << " " << r << endl;
  int x, f;
  cin >> x >> f;
  return mp[{l, r}] = {x, f};
}
inline void solve(int l, int r) {
  if(l > r) return;
  int mid = (l + r) >> 1, x, f;
  tie(x, f) = ask(l, r);
  if(f == r - l + 1) {
    fro(i, l, r) a[i] = x;
    return;
  }
  int y, g, ls, rs;
  tie(y, g) = ask(l, mid);
  if(x == y && g != f) {
    ls = mid - g + 1, rs = ls + f - 1;
    fro(i, ls, rs) a[i] = x;
    solve(l, ls - 1);
    solve(rs + 1, r);
    return;
  }
  if(x == y) {
    solve(l, mid);
    solve(mid + 1, r);
    return;
  }
  tie(y, g) = ask(mid + 1, r);
  if(x == y && g != f) {
    rs = mid + g, ls = rs - f + 1;
    fro(i, ls, rs) a[i] = x;
    solve(l, ls - 1);
    solve(rs + 1, r);
    return;
  }
  solve(l, mid);
  solve(mid + 1, r);
  return;
}

signed main() {
  JYFILE19();
  cin >> n;
  solve(1, n);
  cout << "! ";
  fro(i, 1, n) {
    cout << a[i] << " ";
  }
  cout <<"\n";
  return 0;
}

bool ED;
inline void JYFILE19() {
  // freopen("", "r", stdin);
  // freopen("", "w", stdout);
  ios::sync_with_stdio(0), cin.tie(0);
  double MIB = fabs((&ED-&ST)/1048576.), LIM = 32;
  cerr << "MEMORY: " << MIB << endl, assert(MIB<=LIM);
}

标签:return,Modes,rs,int,题解,mid,solve,ls,CF1372F
From: https://www.cnblogs.com/JiaY19/p/18028078

相关文章

  • CF1845F Swimmers in the Pool 题解
    思路考虑两个人什么时候会相遇。根据小学的相遇追及问题,两人会相遇的条件为:\[2\timesk\timesl=t\times(v1+v2)\]\[2\timesk\timesl=t\times(v1-v2)\]那么对于一个速度\(v\)。它可一相遇的次数即为:\[\frac{t\timesv}{2\timesl}\]当然,这样有可能会算重,也就是在相同......
  • 山海经(线段树)题解
    原题链接:COGS775题目描述:“南山之首曰鹊山。其首曰招摇之山,临于西海之上,多桂,多金玉。有草焉,其状如韭而青华,其名曰祝余,食之不饥……又东三百里,曰堂庭之山,多棪木,多白猿,多水玉,多黄金。又东三百八十里,曰猨翼之山,其中多怪兽,水多怪鱼,多白玉,多蝮虫,多怪蛇,名怪木,不可以上。……”(其实就......
  • 玉蟾宫 题解
    题目描述有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。这片土地被分成N*M个格子,每个格子里写着’R’或者’F’,R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。现在freda要在这里卖萌。。。它要找一块......
  • P6466 分散层叠算法(Fractional Cascading) 题解
    题目链接:分散层叠算法比较妙的东西,在很多涉及到若干个有序块的\(kth\)查询的ynoi题中都有妙用。这里简单提提。两种暴力解法在其他文章已有涉及,在此不再赘述。讲讲具有该怎么写这个算法,首先我们需要预处理出新的\(k\)个序列,不妨记每个为\(M_i\)。\(M_{n}=L_n\),其中\(L\)......
  • [ABC259Ex] Yet Another Path Counting 题解
    Description有\(N\)行\(N\)列的网格图,只能向下或向右走,合法路径的开端和结尾的格子上数字一样找到合法路径条数,对\(998244353\)取模\(1\leqN\leq400,1\leqa_{i,j}\leqN^2\)。Solution有一个\(O(n^4)\)的做法是每次枚举起点和终点然后用组合数计算答案,但是由于同......
  • 牛吃草 题解
    牛吃草居然真的是牛吃草Description由于现代化进程的加快,农场的养殖业也趋向机械化。lyz决定购置若干台自动喂草机来减少自己每天的工作量。为了简化问题,lyz决定将草地建模成一条线段,总长为\(n\),即共有\(n\)个单位长度,编号从左至右为\(1∼n\)。lyz可以在每个单位长度独......
  • blocks 单调栈、单调队列题解
    blocks题解:1、题面:2、分析:题意大概就是说,找一段最长的区间,并且这段区间的平均值>=k,那么我们可以对他的每一个值减去k,最终求和>=0即可。那我们需要对每个可能的左端点和右端点进行考虑,并以此让他们进行配对,看他们之间的区间和是否非负。那么我们先定住一个右端点,再依次考虑......
  • 理想的正方形 题解
    题目描述有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小。输入格式第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。100%的数据2<......
  • P5344 【XR-1】逛森林 题解
    题目链接:逛森林很早就想写写倍增优化建图,尤其是这题,奈何之前知识点没点够,本题线段树优化建图要优一些,不再赘述,没注意\(m\)是\(1e6\),挂了\(n\)多发才发现。后续再详细讲解倍增优化建图,这里简述本题做法。倍增优化建图其实和线段树优化建图恰不多的思想,为倍增求\(LCA\)的每......
  • 2024年2月21号题解
    106.从中序与后序遍历序列构造二叉树力扣题目链接解题思路找到根节点在中序序列的位置计算左子树的节点个数开辟一个节点,并把根节点的值赋值给这个节点根节点的左孩子和右孩子重复上面几个步骤代码实现/***Definitionforabinarytreenode.*structTreeNode{......