首页 > 其他分享 >CodeForces 1900F Local Deletions

CodeForces 1900F Local Deletions

时间:2023-12-03 22:23:24浏览次数:31  
标签:Deletions begin vc int res CodeForces pb typedef Local

洛谷传送门

CF 传送门

操作没有什么性质,唯一一个性质是,操作次数不超过 \(\log n\)(每次至多保留一半元素)。于是我们可以直接模拟操作。

但是肯定不能直接模拟。考虑先对原序列模拟一次,求出经过 \(i\) 次操作后保留的位置集合 \(S_i\)。那么只保留 \([l, r]\) 的元素,可能会造成端点处的元素由不是局部最值变成是局部最值。同时因为新添了这些元素,和它们相邻的元素可能会由是局部最值变成不是局部最值。

考虑如下的递归过程。维护当前进行了 \(i\) 次操作,位置集合是 \(L \cup S_{i, l \sim r} \cup R\)(要维护 \(L, R\))。如果 \(r - l + 1 \le 1\),就可以直接模拟;否则考虑 \(S_{i, l}\) 和 \(S_{i, r}\) 的变化,可以先把 \(S_{i, l}\) 加入 \(L\),把 \(S_{i, r}\) 加入 \(R\),假设把 \(S_{i, l + 1}\) 加入 \(L\),把 \(S_{i, r - 1}\) 加入 \(R\),然后模拟一次。计算下一层的 \(l, r\),分别 upper_bound 和 lower_bound 一次即可。

时间复杂度 \(O(n + q \log^2 n)\)。

code
// Problem: F. Local Deletions
// Contest: Codeforces - Codeforces Round 911 (Div. 2)
// URL: https://codeforces.com/problemset/problem/1900/F
// Memory Limit: 256 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;
typedef vector<int> vi;

const int maxn = 100100;

int n, m, a[maxn];
vi b[20];

inline vi work(vi vc, int op) {
	if ((int)vc.size() <= 1) {
		return vc;
	}
	int n = (int)vc.size();
	vi res;
	if (op) {
		if (a[vc[0]] < a[vc[1]]) {
			res.pb(vc[0]);
		}
		for (int i = 1; i + 1 < n; ++i) {
			if (a[vc[i - 1]] > a[vc[i]] && a[vc[i]] < a[vc[i + 1]]) {
				res.pb(vc[i]);
			}
		}
		if (a[vc[n - 2]] > a[vc[n - 1]]) {
			res.pb(vc[n - 1]);
		}
	} else {
		if (a[vc[0]] > a[vc[1]]) {
			res.pb(vc[0]);
		}
		for (int i = 1; i + 1 < n; ++i) {
			if (a[vc[i - 1]] < a[vc[i]] && a[vc[i]] > a[vc[i + 1]]) {
				res.pb(vc[i]);
			}
		}
		if (a[vc[n - 2]] < a[vc[n - 1]]) {
			res.pb(vc[n - 1]);
		}
	}
	return res;
}

void solve() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
		b[0].pb(i);
	}
	for (int i = 1; i < 20; ++i) {
		b[i] = work(b[i - 1], i & 1);
	}
	while (m--) {
		int l, r;
		scanf("%d%d", &l, &r);
		--l;
		--r;
		vector<int> L, R;
		for (int i = 0;; ++i) {
			if (l >= r) {
				for (int j = l; j <= r; ++j) {
					L.pb(b[i][j]);
				}
				for (int j : R) {
					L.pb(j);
				}
				while ((int)L.size() > 1) {
					L = work(L, (i & 1) ^ 1);
					++i;
				}
				printf("%d\n", a[L[0]]);
				break;
			}
			L.pb(b[i][l]);
			L.pb(b[i][l + 1]);
			L = work(L, (i & 1) ^ 1);
			if (L.back() == b[i][l + 1]) {
				L.pop_back();
			}
			R.insert(R.begin(), b[i][r]);
			R.insert(R.begin(), b[i][r - 1]);
			R = work(R, (i & 1) ^ 1);
			if (R[0] == b[i][r - 1]) {
				R.erase(R.begin());
			}
			l = upper_bound(b[i + 1].begin(), b[i + 1].end(), b[i][l]) - b[i + 1].begin();
			r = lower_bound(b[i + 1].begin(), b[i + 1].end(), b[i][r]) - b[i + 1].begin() - 1;
		}
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:Deletions,begin,vc,int,res,CodeForces,pb,typedef,Local
From: https://www.cnblogs.com/zltzlt-blog/p/17873922.html

相关文章

  • Codeforces Round 911 (Div. 2)
    Preface忙里偷闲补一下之前欠下的一些CF这场前5个题都极其一眼,然而F瞪了好久愣是屁都不会感觉现在水平有有点到瓶颈了,以前是Div2D写完卡现在是Div2E写完卡,但至少还是在进步的A.CoverinWater如果存在某个空地块的长度大于\(2\)则可以用两个块造出无限水,否则答案就是所有空......
  • Codeforces Round 881 (Div. 3)
    CodeforcesRound881(Div.3)A:ABCA.SashaandArrayColoring题意:求最大的着色成本(着色成本是指同一个颜色的最大值-最小值)思路:肯定不能是相同的,直接最大-最小就行#include<bits/stdc++.h>usingnamespacestd;inta[60];voidsolve(){intn;cin>>n;......
  • [Codeforces] CF1807E Interview
    题目翻译有\(n\)堆石头,其中\(n-1\)堆都只有重量为一克的石头,剩下一堆有则有一块有两克的石头和若干重量为一克的石头。你的任务是在\(30\)次询问内推理出那一堆有重量为两克的石头是第几堆。首先输入\(n\),接下来输入\(n\)个数\(a_1,a_2\dotsa_n\),其中\(a_i\)表示......
  • Codeforces Round 911 (Div. 2)
    CodeforcesRound911(Div.2)A-CoverinWaterintmain(){IOS;for(cin>>_;_;--_){cin>>n>>s+1;intans=0;boolf=0;for(inti=1,j=1;i<=n;i=++j)if(s[i]=='......
  • Codeforces Round 904 (Div. 2) C. Medium Design
    jly:开始的想法:首先枚举max的位置。包含它的一定是全加,剩下的一定都不加。然后求所有位置的最小值。初始全0,枚举max之后,因为是加区间,min一定在两端(最左或最右)。所以不需要枚举max,我们枚举min就好(因为加区间和初始全0,这个题的特殊性)。写法注意的点:下标从0开始,区间的左端点都-1,右端......
  • [Codeforces] CF1733C Parity Shuffle Sorting
    题面翻译给定一个长度为\(n\)的数组,你可以对它进行不超过\(n\)次操作。对于每次操作:选择两个下标\(l,r\),满足\(1\leql<r\leqn\);若\(a_l+a_r\)为奇数,将\(a_r\)赋值为\(a_l\),否则将\(a_l\)赋值为\(a_r\)。求一种方案,使得操作后的数组单调不减(即\(a_1\leq......
  • Codeforces Round 912 (Div. 2)
    A.HalloumiBoxes题意:长度为n的数组,你可以逆转最多k长度,问你能不能是数组递增思路:如果k>=2那么每个数都可以两两交换,如果下表1的地方是1就一定可以,k=1的话单独讨论usingnamespacestd;voidsolve(){ intn,k; cin>>n>>k; vector<int>a(n+1); for(inti=1;i<=n;i++){ ......
  • Codeforces Round 908 (Div. 2)
    总结T1题目大意:A,B两人玩游戏,游戏规则如下:整场游戏有多轮,每轮游戏先胜\(X\)局的人获胜,每场游戏先胜\(Y\)局的人获胜。你在场边观看了比赛,但是你忘记了\(x\)和\(y\),只记得总共比了\(1\len\le20\)局,和每局获胜的人,请判断谁获胜了。如果A获胜,输出A,如果B获胜,输......
  • CodeForces 1526F Median Queries
    洛谷传送门CF传送门首先,如果我们确定了\(1,2\)或\(n-1,n\)的位置,我们就能求出原排列。因为题目给了\(p_1<p_2\),所以可以不考虑对称性。也就是说我们知道两个位置是\(1,2\)或\(n-1,n\)但不确定究竟是\(1,2\)还是\(n-1,n\)也可以。然后,如果我们确定......
  • Codeforces Round 878 (Div. 3)
    CodeforcesRound878(Div.3)A:ABCA.CipherShifer题意:在自身后面添加一个字母,但是不能添加自身思路:找到第二个与自身相符的就再找#include<bits/stdc++.h>usingnamespacestd;constintMAX=110;chara[MAX];voidsolve(){intn;cin>>n;for(......