首页 > 其他分享 >题解:AT_abc388_g [ABC388G] Simultaneous Kagamimochi 2

题解:AT_abc388_g [ABC388G] Simultaneous Kagamimochi 2

时间:2025-01-12 09:15:40浏览次数:1  
标签:return int 题解 operator Simultaneous Kagamimochi Modint friend mod

鉴于本题解书写时洛谷题面暂无中文翻译,为避免可能的歧义或困惑,先对本题解中的译法进行约定:(顺便吐槽音译怪)

  • 英文题面中“mochi”或日文题面中“餅”译为“饼”。
  • 英文题面中“kagamimochi”或日文题面中“鏡餅”译为“镜饼”。

鉴于本题是 C 和 E 的加强版,而我懒得去写那两题的题解,这里不加证明地给出那两题的做法:

  • C:对于每个饼,双指针求出大小不超过其一半的最后一个饼的位置。
  • E:二分答案 \(k\),check 是否前 \(k\) 个饼可以依次和后 \(k\) 个饼组合成镜饼。

朴素写法 E 的 check 是 \(O(n)\) 的,我们只要将其优化到 \(O(1)\),就可以直接套用过来通过本题。

这时候 C 就给了我们启发。我们预处理出 C 的位置数组 \(pos\),并定义下标差数组 \(dis_i=i-pos_i\)。容易发现,二分的答案为 \(k\) 时,E 的 check 等价于判断 \(\max\limits_{i=r-k+1}^{r}\{dis_i\}\le (r-k+1)-l\) 是否成立。使用 ST 表维护 \(dis\) 的区间最值即可。

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

// Problem: G - Simultaneous Kagamimochi 2
// Contest: AtCoder - HHKBプログラミングコンテスト2025(AtCoder Beginner Contest 388)
// URL: https://atcoder.jp/contests/abc388/tasks/abc388_g
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

//By: OIer rui_er
#include <bits/stdc++.h>
#define rep(x, y, z) for(int x = (y); x <= (z); ++x)
#define per(x, y, z) for(int x = (y); x >= (z); --x)
#define debug(format...) fprintf(stderr, format)
#define fileIO(s) do {freopen(s".in", "r", stdin); freopen(s".out", "w", stdout);} while(false)
#define endl '\n'
using namespace std;
typedef long long ll;

mt19937 rnd(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
int randint(int L, int R) {
    uniform_int_distribution<int> dist(L, R);
    return dist(rnd);
}

template<typename T> void chkmin(T& x, T y) {if(y < x) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}

template<int mod>
inline unsigned int down(unsigned int x) {
	return x >= mod ? x - mod : x;
}

template<int mod>
struct Modint {
	unsigned int x;
	Modint() = default;
	Modint(unsigned int x) : x(x) {}
	friend istream& operator>>(istream& in, Modint& a) {return in >> a.x;}
	friend ostream& operator<<(ostream& out, Modint a) {return out << a.x;}
	friend Modint operator+(Modint a, Modint b) {return down<mod>(a.x + b.x);}
	friend Modint operator-(Modint a, Modint b) {return down<mod>(a.x - b.x + mod);}
	friend Modint operator*(Modint a, Modint b) {return 1ULL * a.x * b.x % mod;}
	friend Modint operator/(Modint a, Modint b) {return a * ~b;}
	friend Modint operator^(Modint a, int b) {Modint ans = 1; for(; b; b >>= 1, a *= a) if(b & 1) ans *= a; return ans;}
	friend Modint operator~(Modint a) {return a ^ (mod - 2);}
	friend Modint operator-(Modint a) {return down<mod>(mod - a.x);}
	friend Modint& operator+=(Modint& a, Modint b) {return a = a + b;}
	friend Modint& operator-=(Modint& a, Modint b) {return a = a - b;}
	friend Modint& operator*=(Modint& a, Modint b) {return a = a * b;}
	friend Modint& operator/=(Modint& a, Modint b) {return a = a / b;}
	friend Modint& operator^=(Modint& a, int b) {return a = a ^ b;}
	friend Modint& operator++(Modint& a) {return a += 1;}
	friend Modint operator++(Modint& a, int) {Modint x = a; a += 1; return x;}
	friend Modint& operator--(Modint& a) {return a -= 1;}
	friend Modint operator--(Modint& a, int) {Modint x = a; a -= 1; return x;}
	friend bool operator==(Modint a, Modint b) {return a.x == b.x;}
	friend bool operator!=(Modint a, Modint b) {return !(a == b);}
};

const int N = 5e5 + 5;

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

struct SparseTable {
    int mx[18][N];
    void init(int* a, int n) {
        rep(i, 1, n) mx[0][i] = a[i];
        rep(j, 1, 17) rep(i, 1, n - (1 << j) + 1) mx[j][i] = max(mx[j - 1][i], mx[j - 1][i + (1 << (j - 1))]);
    }
    int ask(int l, int r) {
        if(l > r) return -2e9;
        int k = __lg(r - l + 1);
        return max(mx[k][l], mx[k][r - (1 << k) + 1]);
    }
}st;


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n;
    rep(i, 1, n) cin >> a[i];
    cin >> m;
    int ptr = 0;
    rep(i, 1, n) {
        while(ptr < n && a[ptr + 1] * 2 <= a[i]) ++ptr;
        dis[i] = i - ptr;
        // cout << dis[i] << " \n"[i == n];
    }
    st.init(dis, n);
    rep(i, 1, m) {
        int ql, qr;
        cin >> ql >> qr;
        int l = 0, r = (qr - ql + 1) / 2 + 1;
        while(l < r) {
            int mid = (l + r) >> 1;
            if(st.ask(qr - mid + 1, qr) <= (qr - mid + 1) - ql) l = mid + 1;
            else r = mid;
        }
        cout << l - 1 << endl;
    }
    return 0;
}

标签:return,int,题解,operator,Simultaneous,Kagamimochi,Modint,friend,mod
From: https://www.cnblogs.com/ruierqwq/p/18666533/abc388g

相关文章

  • 2025/1/11 第25场蓝桥入门赛 题解
    A: 哪来的AC  :  题目链接水题:31画#include<iostream>usingnamespacestd;intmain(){//请在此输入您的代码cout<<31;return0;}B: 酒店安排  : 题目链接 思路:从大到小排序,求每两个相邻房间的差值 ,滑动窗口求m-1个差值最小,即为答案要想最......
  • 题解:P1970 [NOIP2013 提高组] 花匠
    闲话本文同步发布在cnblogs。正题容易发现此题要求花必须一高一低摆放。最优化问题,看不出怎么贪心,遂DP。设计状态\(f_{i,0}\)表示当前为上升形势最长花序列,\(f_{i,1}\)表示当前为下降形势最长花序列。状态转移由于需要一高一低,易得:\[f_{i,0}=\begin{cases}......
  • P3247 [HNOI2016] 最小公倍数 题解
    \(\text{P3247[HNOI2016]最小公倍数题解}\)第一眼上去没什么明显的思路。图上问题一般没有什么好的多项式复杂度算法来解决。观察数据范围,注意到\(n,q\le5\times10^4\),是一个典型的根号复杂度算法,于是考虑分块来处理。注意到所求的不一定是简单路径,也就是在不超过所需要的......
  • P10200 花神诞日 题解
    P10200[湖北省选模拟2024]花神诞日题解首先注意到一个集合中两两异或和的最小值就是,排序后相邻两个数异或和的最小值。证明可以考虑放到01-Trie上,从高往低位建树,求一个数与之异或的最小值,就是使高位相同位数尽可能多,则就是01-Trie上的前一个叶子或后一个叶子。由此,我们......
  • 题解:P2296 [NOIP2014 提高组] 寻找道路
    条件第一步,要能到达\(t\)点,建反图跑一遍。记录哪些点可行。第二步,扫描每个点,若其旁边均为标记过的,说明点的出边所指向的点都直接或间接与终点连通。记录这个点第二次第三步,在原边枚举每条边,若两个节点均被记录了第二次,加入一个新图,否则扔掉。对新图进行BFS即可。代码:#inc......
  • 题解:P2822 [NOIP2016 提高组] 组合数问题
    组合数,还是多测,考虑预处理所有答案。组合数的递推公式如下,证明在本文底部:\[C_{i,j}=C_{i-1,j}+C_{i-1,j-1}\]由于求的是是否能被\(k\)整除,转化式子为:\[C_{i,j}=(C_{i-1,j}+C_{i-1,j-1})\bmodk\]易得若\(C_{i,j}=0\)即为可整除。但这样每次......
  • 洛谷B3733 [信息与未来 2017] 基因组分析密码锁题解
    [信息与未来2017]密码锁题目描述乌龟给自己的贵重物品上了密码锁。密码锁上有5 个数字拨盘。每个数字拨盘每次向上拨使数字增加1 (9 向上拨得到0),向下拨使数字减少1 (0 向下拨得到9)。拨盘上的数字组成一个5 位数。只要拨盘上的数字变为素数,密码锁就会被解开。素......
  • CF1759F题解
    BriefDescription给你一个\(n\)位的\(p\)进制数,第\(i\)位为\(a_i\)。请问最少要让该数加多少次\(1\),可以让数码\(0,\cdots,p−1\)都出现过(包含在中间过程出现)。Solution因为是\(p\)进制,不难发现答案一定不会超过\(p−1\),也就是说在最坏情况下就是其最后一位加至......
  • THUPC 2025 初赛 部分题题解
    持续更新中,目前只有\(\texttt{A,D,G,H,I,M}\)题题解。A.骑行计划题目描述小Rei有\(n\)天的假期,第\(i\)天她要骑行\(s_i\)分钟,每分钟骑行费用为\(c\)元。有\(m\)种骑行卡,第\(i\)种骑行卡售价\(w_i\)元,有效期\(d_i\)天,免费时间\(t_i\)分钟。小Rei可以......
  • 【机器人学和计算机视觉】SLAM(Simultaneous Localization and Mapping)原理与技术实现
    引言SLAM(SimultaneousLocalizationandMapping,即时定位与地图构建)是机器人学和计算机视觉领域的一项关键技术。它允许机器人在未知环境中自主导航,同时构建环境的地图并确定自身的精确位置。SLAM技术在机器人、无人驾驶、增强现实和无人机等领域有着广泛的应用。本文将......