首页 > 其他分享 >P8543 「Wdoi-2」纯粹的复仇女神 题解

P8543 「Wdoi-2」纯粹的复仇女神 题解

时间:2023-11-25 16:14:08浏览次数:25  
标签:back int 题解 fro mid P8543 Wdoi eb define

自己的套路还是见少了。

思路

考虑扫描线。

每一个颜色的 \(\min\) 具有单调性,这个很好看出来。

可以使用一个单调栈来维护。

这里都是朴素的。

考虑如何维护。

我们发现在通过单调栈维护的时候。

需要支持撤销上一个元素对区间的影响。

我就在这里卡了很久。

我们有一个很暴力的想法。

我们每一次区间取 \(\max\) 时,我们将这个元素留下来,直接存着。

然后在撤销影响的时候就可以删掉这个点。

发现可以线段树做。

每个点维护一个可删堆。

使用标记永久化的思想。

这样每一次插入时只会增加 \(\log\) 个值。

删除的时候也恰好时这 \(\log\) 个位置。

至于可删堆如何维护。

我们可以拿两个优先队列模拟。

加入时丢进一个优先队列,删除时丢进另一个。

查询时先将堆顶相同的不断弹掉就可以了。

Code

代码就比较简单。

/**
 * @file P8543.cpp
 * @author mfeitveer
 * @date 2023-11-25
 * 
 * @copyright Copyright (c) 2023
 * 
 */
#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
#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--)
#define dbg cerr << "Line " << __LINE__ << ": "
#define EVAL(x) #x " = " << (x)

typedef int64_t i64;
typedef uint32_t u32;
typedef uint64_t u64;
typedef __int128_t i128;
typedef __uint128_t u128;
typedef pair<int, int> PII;

bool ed;

const int N = 200010;
const int M = 1000010;
const int mod = 998244353;

int n, m, a[N], c[N], l[N], r[N], ans[M];
vector<int> to[N];
vector<PII> que[N];
priority_queue<int> t1[N<<1], t2[N<<1];

inline void ins(int p, int l, int r, int ls, int rs, int k)
{
	if(ls <= l && r <= rs)
		return t1[p].push(k), void();
	int mid = (l + r) >> 1;
	if(mid >= ls) ins(mid<<1, l, mid, ls, rs, k);
	if(mid <  rs) ins(mid<<1|1, mid + 1, r, ls, rs, k);
}
inline void del(int p, int l, int r, int ls, int rs, int k)
{
	if(ls <= l && r <= rs)
		return t2[p].push(k), void();
	int mid = (l + r) >> 1;
	if(mid >= ls) del(mid<<1, l, mid, ls, rs, k);
	if(mid <  rs) del(mid<<1|1, mid + 1, r, ls, rs, k);
}
inline void calc(int p)
{
	while(!t1[p].empty() && !t2[p].empty() && t1[p].top() == t2[p].top())
		t1[p].pop(), t2[p].pop();
}
inline int ask(int p)
	{ return (t1[p].empty() ? 0 : t1[p].top()); }
inline int ask(int p, int l, int r, int k)
{
	calc(p);
	if(l == r) return ask(p); int mid = (l + r) >> 1;
	if(mid >= k) return max(ask(p), ask(mid<<1, l, mid, k));
	return max(ask(p), ask(mid<<1|1, mid + 1, r, k));
}
inline void solve()
{
	cin >> n >> m; int x, y;
	fro(i, 1, n) cin >> c[i];
	fro(i, 1, n) cin >> a[i];
	fro(i, 1, n) to[i].eb(0);
	fro(i, 1, m) cin >> x >> y, que[y].eb(x, i);
	fro(i, 1, n)
	{
		while(a[to[c[i]].back()] > a[i])
			x = to[c[i]].back(), to[c[i]].pop_back(),
			del(1, 1, n, l[x], r[x], a[x]);
		r[i] = i, l[i] = to[c[i]].back() + 1, to[c[i]].eb(i);
		ins(1, 1, n, l[i], r[i], a[i]);
		for(auto [l, id] : que[i]) ans[id] = ask(1, 1, n, l);
	}
	fro(i, 1, m) cout << ans[i] << "\n";
}

bool st;

signed main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	double Mib = fabs((&ed-&st)/1048576.), Lim = 1024;
	cerr << " Memory: " << Mib << "\n", assert(Mib<=Lim);
	solve();
	return 0;
}

标签:back,int,题解,fro,mid,P8543,Wdoi,eb,define
From: https://www.cnblogs.com/mfeitveer/p/17855610.html

相关文章

  • 14:苏格拉底问答、实践过程截图、遇到问题解决问题截图,代码链接、
    ......
  • 苏格拉底问答、实践过程截图、遇到问题解决问题截图,代码链接
    include<stdio.h>include<stdlib.h>include<sys/types.h>include<sys/socket.h>include<netinet/in.h>include<arpa/inet.h>include<time.h>include<string.h>include<unistd.h>defineMAXLINE256......
  • 两道题解决滑动窗口问题
    定长567.字符串的排列-力扣(LeetCode)给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。换句话说,s1 的排列之一是 s2 的 子串 。解题思路1°传统套路就是定义两个哈希表,一个存储s1中每个字符的出现次数,记s1......
  • P1002题解
    思路设\(dp_{i,j}\)表示第\(i\)行\(j\)列卒走到这里有多少种方式。卒是可以向右和下走,所以到这个点只能从左或上来,不难得出转移公式:\(dp_{i,j}=dp_{i-1,j}+dp_{i,j-1}\)。如果马在这个点上或者说马能到这个点上,那么卒不能到这个点,也就是卒到这个点的方式为\(0\)。如......
  • P1135题解
    思路我写的好像是动规的做法。设\(f_{i,j}\)表示第\(i\)步\(j\)个点是否可以走到,值要么为\(1\),要么为\(0\)。最多走\(n\)步,因为总共只有\(n\)个点,每一步都肯定会多延伸出一个点,要不然就重复计算。不难得出转移公式:\(f_{i+1,j+k_j}=f_{i,j}\)\(f_{i+1,j-k_j}=f_{......
  • P1003题解
    简单模拟题。思路枚举每一个地毯,因为后面的会覆盖前面的,所以从正序枚举。如果要求的点的坐标在当前地毯上,则将答案赋值为当前地毯编号。最后输出答案。那如果这个点没有地毯呢?答案初始设为\(-1\),这样没有地毯覆盖的话,答案不会改变,这样输出答案就会是\(-1\)。注意:记得赋初......
  • SP9199题解
    考察了小学奥数知识,不会的请先去学习一下相遇与追及。思路两个人相遇的点一定是有周期性的,我们可以先算出一个周期会走多远,而这个距离是两人速度的最小公倍数。接着需分情况讨论。如果两人是同向,则为追及,需用距离除以一人的速度减去距离除以另一人的速度。需要取绝对值。......
  • P5163 WD与地图 题解
    来一发分治题解吧。感觉和单纯的整体二分还是有一点区别。虽然整体二分也能看作分治就是了。思路首先时光倒流。删边改为加边。这没有什么好说的,比较基础。我们考虑在不断加边时,每两个点是在什么时候变成一个强连通分量里面的。考虑分治。首先在\([l,r]\)内选取中点\(......
  • [ABC327D] Good Tuple Problem 题解
    分析:这一道题很容易发现可以用并查集来维护(不知道为什么其他人都用了图论),\(a_i\)与其对应的\(b_i\)代表着\(a_i\)这个集合里不能存在着\(b_i\)。根据只有存在两个集合,所以我们会发现,若\(x\)与\(y\)不在一个集合且\(x\)与\(z\)也不在一个集合,那么\(x\)和\(y\)......
  • [ABC328C] Consecutive 题解
    给一个长度为\(n\)的字符串\(s\),\(q\)次询问,每一次\(l\)和\(r\)区间内有多少个\(s_i\)等于\(s_{i-1}\)。\(10^5\)的数据\(O(N^2)\)暴力肯定行不通。于是我们考虑预处理前缀和,处理到\(i\)下标以及之前有多少个\(s_i\)等于\(s_{i-1}\)。每一次查询\(O(1)\)回......