首页 > 其他分享 >CF1905D Cyclic MEX 题解

CF1905D Cyclic MEX 题解

时间:2024-02-20 15:24:07浏览次数:26  
标签:int 题解 sum ans back mex CF1905D text MEX

题意:给定一个长度为 \(n\) 的排列 \(a\),\(a_i \in [0,n-1]\)。你可以将这个排列进行循环移位,最小化 \(\sum_{i=1}^{n} \text{mex}_{j=1}^i a_j\) 的值。

首先我们可以先计算出最初情况下每一个 \(i\) 位置的 \(\text{mex}\) 值。这个序列一定是单调非严格递增的。

首先有一个比较显然的 \(\text{Trick}\):\(\text{mex}_{j=1}^{i}a_j=\min_{j=i+1}^n a_j\)。

考虑将 \(a_1\) 循环移到第 \(n\) 位后会有什么影响。首先所有位置的 \(\text{mex}\) 值都要向左移动一位,第 \(n\) 位的值一定还是 \(n\)。对于现在 \(1\) 到 \(i-1\) 位上的值,因为第 \(n\) 位上的值变为了 \(a_1\),而原来这些位置并没有算上 \(a_1\) 对他们的贡献,所以这些位置上的值都要和 \(a_1\) 取 \(\min\)。

上述过程可以用单调队列维护。具体的,每次循环移位需要执行以下几步操作:

  • 将 \(a_1\)(队首)弹出。

  • 将队尾大于 \(a_1\) 的数弹出,并在队尾插入相等数量的 \(a_1\)。

  • 在队尾插入 \(n\)。

为了保证 \(O(n)\) 的时间复杂度,我们不用插入相同的数,而是直接记录这个数的数量即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair <int,int> pii;
const int MAXN = 1e6 + 10;
typedef pair <int,int> pii;
deque <pii> q;
int t,n,a[MAXN],mex[MAXN],ans,sum;
signed main()
{
	cin >> t;
	while(t--)
	{
		while(!q.empty()) q.pop_front();
		cin >> n;
		for(int i = 1;i <= n;i++) cin >> a[i];
		for(int i = 1;i <= n + 1;i++) mex[i] = 1e18;
		mex[n] = n;
		for(int i = n;i >= 1;i--) mex[i - 1] = min(mex[i],a[i]); 
		mex[0] = -1;ans = 0;
		for(int i = 1;i <= n;i++)
		{
			if(mex[i] != mex[i - 1]) q.push_back(make_pair(mex[i],1));
			else 
			{
				pii tmp = make_pair(q.back().first,q.back().second + 1);
				q.pop_back(),q.push_back(tmp);
			}
			ans += mex[i];
		}
		sum = ans;
		for(int i = 1;i < n;i++)
		{
			sum -= q.front().first;
			if(q.front().second == 1) q.pop_front();
			else q.front().second--;	
			int num = 0;
			while(!q.empty() && q.back().first > a[i]) 
			{
				sum -= q.back().first * q.back().second;
				num += q.back().second;
				q.pop_back();
			}
			sum += n,sum += num * a[i];
			q.push_back(make_pair(a[i],num));
			q.push_back(make_pair(n,1));
			ans = max(ans,sum);
		}
		cout << ans << endl;
	}
    return 0;
}



标签:int,题解,sum,ans,back,mex,CF1905D,text,MEX
From: https://www.cnblogs.com/Creeperl/p/18023188

相关文章

  • CF1893B Neutral Tonality 题解
    很巧妙的一道题。为了让\(\text{LIS}\)长度最小,我们肯定先将\(b\)数组降序排序,这样\(b\)自身对\(\text{LIS}\)的贡献最小。考虑是否存在一种插入方式使得最终\(a\)的\(\text{LIS}\)长度和最初\(a\)的\(\text{LIS}\)长度相等。这时我们会发现,如果我们插入\(b\)......
  • CF638C题解
    我们可以针对一个顶点只能同时修一条边这个条件设计方案。由于每条边都要修一遍,同样某天修理的方案放在哪一天修都无所谓,我们采用贪心的策略,在原有的方案上尽可能多地修边。根据上面的性质,我们只需要将同一顶点的边放在不同的某天修理的方案中,使方案尽可能的少即可。跑一遍dfs......
  • Docker 使用遇到的问题解决 更改Tag
    dockertagconsul:1.15.4consul:latestdockerrmiconsul:1.15.4删除制定版本在运行时,有些镜像拉取时报错我这里 时 consu,只能制定版本下载1.15.4Errorresponsefromdaemon:manifestforconsul:latestnotfound:manifestunknown:manifestunknown ......
  • P2171 Hz吐泡泡 题解
    传送门题目背景Hz大大是一种可爱的动物(神)。他很喜欢吐泡泡(更喜欢写作业)。题目描述这天,Hz大大心血来潮,吐了n个不同的泡泡玩(保证没有重复的泡泡)。因为他还要写作业,所以他请你帮他把这些泡泡排序成树(左子树<=根<右子树)。输出它的后序遍历。输入格式共2行。第一行,1个整数n。(1<......
  • 洛谷P10179 题解
    题意简述给定\(n\)个点,要求构造出一棵树,同时有\(m\)个事件,第\(i\)个事件要求\(u_i\)和\(v_i\)用两条树边连接,即当中相隔一个点。若存在构造方案,输出Yes并输出其中一种方案,否则输出No。思维路径首先简化问题,假如我们想让一堆点互相相隔一个点,我们的做法。考虑菊花......
  • 程序设计天梯赛个人题解 L2-047-2 锦标赛
    题目分析综合题意,将最后一场比赛视为顶层,第一轮比赛视为第一层,则有:下层每场比赛选出一个胜者,每两个下层的胜者间举行本层的一次比赛,显然这是一个二叉树。考虑还原建立每场比赛的树。由于最后一层的比赛是$2^k$个选手参加,故这是个完美二叉树,使用完全二叉树的数组储存方式,则标号......
  • 洛谷-P3380/LibreOJ-106/BZOJ-3196题解
    题意简述给定一个数列,支持以下操作:查询\(k\)在区间内的排名(区间内比\(k\)小的数的个数\(+1\))查询区间内排名为\(k\)的值修改某一位值上的数值查询\(k\)在区间内的前驱(前驱定义为严格小于\(k\),且最大的数,若不存在输出-2147483647)查询\(k\)在区间内的......
  • U41492 树上数颜色 题解
    U41492树上数颜色题目描述给一棵根为1的树,每次询问子树颜色种类数输入格式第一行一个整数n,表示树的结点数接下来n-1行,每行一条边接下来一行n个数,表示每个结点的颜色c[i]接下来一个数m,表示询问数接下来m行表示询问的子树输出格式对于每个询问,输出该子树颜色数输入输出......
  • P2524 Uim的情人节礼物•其之弐 题解
    题目描述前传:详见洛谷P2525Uim成功地按照顺序将礼物送到了 N 个妹子的手里并维持她们的和谐。现在Uim现在想知道,他最终选择的顺序是所有给 N 个妹子送礼顺序中,字典序第几小的。送礼顺序可以看作1,2,⋯,N 的一个排列。输入格式第一行一个整数N,表示有 N 个数。第二......
  • P3411 序列变换 题解
    自己做不出来,看现在题解区的题解讲的都不咋清楚。懂了之后来为后人铺路。而且我的马蜂比较好看题目传送门我能看懂这道题,主要是依靠了这篇题解的帮助。首先我们只关注数的相对关系,所以可以离散化。注意到值域\(10^6\),用数组离散化。这道题可以用贪心做。(有一些定义先往下看)......