zoukankan      html  css  js  c++  java
  • CF1332G No Monotone Triples

    No Monotone Triples

    Given a sequence of integers a of length (n), a tuple ((i,j,k)) is called monotone triples if

    • (1 le i<j<kle n);

    • (a_i le a_j le a_k) or (a_i ge a_j ge a_k) is satisfied.

    Bob is given a sequence of integers (a) of length (n) in a math exam. The exams itself contains questions of form (L, R), for each of them he is asked to find any subsequence (b) with size greater than (2) (i.e. (|b| ge 3)) of sequence (a_L, a_{L+1},ldots, a_{R}).

    However, he hates monotone stuff, and he wants to find a subsequence free from monotone triples. Besides, he wants to find one subsequence with the largest length among all subsequences free from monotone triples for every query.

    Please help Bob find out subsequences meeting the above constraints.

    (3 le n le 2 cdot 10^5, 1 le q le 2 cdot 10^5)

    题解

    https://codeforces.ml/blog/entry/75432

    Observations

    We will solve this task with the following observations.

    • Observation 1. If an array (x) of length (k (k ge 3)) has no monotone triple, then one of the following is true:

      • (x_1< x_2>x_3< x_4>x_5< ldots)

      • (x_1>x_2< x_3>x_4< x_5>ldots)

      显然相邻两个不等式符号不能相同。

    • Observation 2. If an array (x) of length (k (k ge 4)) has no monotone triple, then its subsequence has no monotone triple.

    • Observation 3. If an array (x) of length (4) has no monotone triple, then (max(x_2,x_3)>max(x_1,x_4), min(x_2,x_3)< min(x_1,x_4)),vice versa.

      Proof. WLOG, we assume (max(x_2,x_3)le x_1), by observation 1 we will know that (x_1>x_2< x_3>x_4), since (x_1ge x_3), we get a monotone triple ((1,3,4)), leading to contradiction. Second part can be verified easily.

      这个结论的意思是 (x_1,x_4) 中不能出现最大值和最小值。

    • Observation 4. For every array (x) of length (k (k ge 5)), (x) must have monotone triple.

      Proof. WLOG, we just need to prove the observation holds when (k=5) and cases when not all elements are equal. In that case, one of extremal can be reached in position other than (3). WLOG, we will assume that maximum is reached at position (2). However, (x_2,x_3,x_4,x_5) cannot be monotone-triple-free, leading to contradiction!

      如果 (x_1,x_2,dots,x_5) 不是全相等的话,那么 (x_1,x_2,x_4,x_5) 一定会出现最大值或最小值。此时我们一定可以构造长度为 (4) 的子序列使得最大值或最小值在开头或结尾,违反了结论三。这样长度 (geq 5) 的子序列一定不满足条件。

    Brute Force

    Combining those observations (or Erdos–Szekeres theorem if you know it), we would like to get the following solution, which runs in (O(q n^4)).

    • If the subsequence is monotone, the answer should be (0).

    • If there exists (i,j,k,l) such that (L le i< j< k< l le R) and (a_i, a_l) fails to reach maximum and minimum among those four numbers, the answer should be (4).

    • Otherwise, the answer should be (3).

    (O(qn^4)) 就暴力检查每个长度为 (4) 的子序列即可。

    Faster Solutions

    In the following paragraphs, we will only focus on the case of (4). Other stuffs can be dealt similarly (or easily).

    (O(n^2)) solution(the observation is crucial to obtain a faster solution)

    Notice that constraint is equivalent to that there exists (i,j) such that (a_i,a_j) fails to reach maximum and minimum among (a_i,a_{i+1},ldots,a_j). This observation allows us to solve this task in (O(n^2)) with some precalculation. (though it's still not enough to get accepted).

    说实话我觉得一个Div2的题可以到此为止了。

    (O(n log n)) solution

    Let's solve the task for a sequence of a pairwise distinct numbers and then change the conditions to a general sequence.

    Let's fix (a_i) — the leftmost element of (b) and look at what we are asked to find. So there should be some position (j) to the right of (i) so that the range of values on positions ([i, j]) excluding the greatest and the smallest values includes both (a_i) and (a_j).

    Let's process the array from right to left, maintaining two stacks. The top element in both stacks is the currently processed one. Next element of the first stack is the closest to the right element greater than the top one, and the next element of the second stack is the closest to the right smaller than the top one. And the stacks go like that until the end of array. 维护最大值和最小值的单调栈。

    Iterating over one of these stacks will show the increase of the range of values in one direction, iterating over both at the same time will show how the range of values changes in total.

    So I claim that the sequence we are looking for exists if both stacks include more than (1) element and there is an element to the right of second elements of both stacks such that it is included in neither of the stacks. Naturally that condition tells that there is some position in which neither maximum, nor minimum values are updated. 找到右侧的一个位置并避免它是子串的最大值或最小值即可。

    The values that are in neither of stacks can be maintained in a queue or in a BIT.

    Basically, the position when the range of values doesn't change is such a value which is both smaller than the maximum value on the segment and greater than the minimum one. Thus, we can choose (a_i), the latest elements in both stacks up to that position and that position itself. 构造方法就是选择 ({a_i,max,min,a_j})

    How to deal with not pairwise distinct elements? Well, it's enough to change the conditions in stacks to the next greater or equal and the next smaller or equal. However, that will push the elements equal to the current one right next to it to the both stacks. Previously we kinda used the fact that no element except the current one is in both stacks. I think that the easiest way to deal with it is to get the answer for the rightmost of the consecutive equal elements and then just say that the answer for the rest of them is the same. Finally, push all these consecutive equal elements to the both stacks. 右侧相等的元素不能充当我们构造的序列中的最大值或最小值,所以要跳过栈中相等的元素。一个小优化:连续相等的元素段的答案都等于右端点元素的答案。

    As for queries. I previously said that we can take the position where the value range doesn't change. Basically, the first valid position is coincidentally the shortest length valid segment starting from (i). So to find the first position you just need to do a binary search over that queue or BIT of the values which are in neither of the stacks. We can easily remember it for each position and then do a range minimum query checking if any of the positions in ([l, r]) have their shortest right border smaller than (r). 询问就是个二维偏序问题。

    CO int N=2e5+10;
    int a[N],t[N];
    vector<int> mn,mx;
    set<int> s;
    int p3[N],p4[N];
    array<int,3> ans3[N];
    array<int,4> ans4[N];
    
    int main(){
    	int n=read<int>(),m=read<int>();
    	for(int i=1;i<=n;++i) read(a[i]);
    	
    	s.insert(n+1);
    	int lmn=0,lmx=0;
    	for(int r=n,l;r>=1;r=l-1){
    		for(l=r;l>1 and a[l-1]==a[r];--l);
    		
    		for(;mn.size() and a[r]<a[mn.back()];mn.pop_back(),lmn=0)
    			if(--t[mn.back()]==0) s.insert(mn.back());
    		for(;mx.size() and a[r]>a[mx.back()];mx.pop_back(),lmx=0)
    			if(--t[mx.back()]==0) s.insert(mx.back());
    		
    		p3[r]=r+max(lmn,lmx)+1;
    		ans3[r]={r,p3[r]-1,p3[r]};
    		
    		int x=lower_bound(mn.begin(),mn.end(),r,[](int i,int j)->bool{
    			return a[i]<a[j];
    		})-mn.begin()-1; // second elements of both stacks
    		int y=lower_bound(mx.begin(),mx.end(),r,[](int i,int j)->bool{
    			return a[i]>a[j];
    		})-mx.begin()-1; // skip the equal elements
    		
    		if(x!=-1 and y!=-1){
    			p4[r]=*s.upper_bound(max(mn[x],mx[y]));
    			int u=*upper_bound(mn.begin(),mn.end(),p4[r],greater<int>());
    			int v=*upper_bound(mx.begin(),mx.end(),p4[r],greater<int>()); // the latest elements in both stacks up to that position
    			if(p4[r]<=n) ans4[r]={r,min(u,v),max(u,v),p4[r]};
    		}
    		else p4[r]=n+1;
    		
    		mn.push_back(r),++lmn;
    		mx.push_back(r),++lmx; // length of the longest monotone prefix of suffix[r]
    		t[r]+=2; // number of occurrences 
    		
    		if(r<n and p3[r]>p3[r+1])
    			p3[r]=p3[r+1],ans3[r]=ans3[r+1];
    		if(r<n and p4[r]>p4[r+1])
    			p4[r]=p4[r+1],ans4[r]=ans4[r+1];
    		
    		for(int i=r-1;i>=l;--i){
    			p3[i]=p3[r],ans3[i]=ans3[r];
    			p4[i]=p4[r],ans4[i]=ans4[r];
    			mn.push_back(i),++lmn;
    			mx.push_back(i),++lmx;
    			t[i]+=2;
    		}
    	}
    	while(m--){
    		int l=read<int>(),r=read<int>();
    		if(r>=p4[l]){
    			puts("4");
    			for(int x:ans4[l]) printf("%d ",x);
    			puts("");
    		}
    		else if(r>=p3[l]){
    			puts("3");
    			for(int x:ans3[l]) printf("%d ",x);
    			puts("");
    		}
    		else puts("0"),puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    离线安装 Framework 3.5 镜像安装
    换行符处理
    使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength 属性设置的值。
    vs 无法启动iis express web服务器
    OracleInternal.MTS.DTCPSPEManager”的类型初始值设定项引发异常
    纯前端上传文件FormData----注意的地方
    LINQ 的一些相关基本语法
    Spread JS 随笔四 相关用法
    Spread JS 随笔三 列设置
    findbugs报OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE的修改实例
  • 原文地址:https://www.cnblogs.com/autoint/p/12616256.html
Copyright © 2011-2022 走看看