zoukankan      html  css  js  c++  java
  • 牛客练习赛85-哲学家的沉思 #倍增##单调栈#

    牛客练习赛85-哲学家的沉思 #倍增##单调栈#

    题目大意

    给定(n)个数字,第(i)个为(a_i), 有(q)个询问,对于每个询问,给定(l,r),将序列([l,r])划分为最少的子序列,使得每个子序列的第一个数在该子序列内最大

    复杂度要求:(O(qlog n))

    读入:

    n q
    a1 a2 ... a_n
    l1 r1
    l2 r2
    ...
    l_q r_q
    

    样例一

    输入

    5 2
    2 5 4 3 6
    3 5
    1 2
    

    输出

    2
    2
    

    说明

    对于询问1,可以把[3,5]划分为[3,4],[5,5]。对于询问2,可以把[1,2]划分为[1,1],[2,2]。
    

    样例二

    输入

    3 2
    2 2 3
    1 2
    1 3
    

    输出

    1
    2
    

    说明

    对于询问1,可以把[1,2]划分为[1,2]。对于询问2,可以把[1,3]划分为[1,2],[3,3]。
    

    思路

    不难的一道题,容易发现,题目要求的是以(l)开头的,在([l,r])范围内的严格上升(可不连续)子序列的长度用样例一的第一个询问举例,[3,5]包含序列4,3,6,以4开头的严格上升子序列为:4,6,所以输出2

    不难想到倍增,(f_{i,j})表示第(i)位后面比(a_i)大的第(2^j)个数的下标,用类似倍增LCA的方式求解即可

    代码

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int read(){
    	int re = 0 , sig = 1;
    	char c = getchar();
    	while(c < '0' || c > '9'){
    		if(c == '-')sig = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9'){
    		re = (re << 1) + (re << 3) + c - '0';
    		c = getchar();
    	}
    	return re * sig;
    }
    #define N 100010
    int n , q;
    int Stack[N] , top = 0;
    int *stack = Stack + 1;
    int a[N];
    
    int f[N][25];
    int main() {
    	n = read() , q = read();
    	for(int i = 1 ; i <= n ; i++)
    		a[i] = read();
    	
    	for(int i = 1 ; i <= n ; i++) {//找比a[i]大的第一个a[j] (j>i)即f[i][0], 单调栈解决
    		while(a[stack[top - 1]] < a[i] && top > 0) {
    			f[stack[top - 1]][0] = i;
    			--top;
    		}
    		stack[top] = i;
    		++top;
    	}
    	while(top > 0) {
    		f[stack[top - 1]][0] = n + 1;
    		--top;
    	}
    	
    	for(int i = 0 ; i <= 20 ; i++)//求f
    		f[n + 1][i] = n + 1;
    	for(int i = 1 ; i <= 20 ; i++)
    		for(int j = n ; j > 0 ; j--)
    			f[j][i] = f[ f[j][i - 1] ][i - 1];
    			
    	
    	while(q--) {
    		int l = read() , r = read();
    		int ans = 0;
    		for(int i = 20 ; i >= 0 ; i--) {
    			if(f[l][i] <= r) {
    				l = f[l][i];
    				ans += (1 << i);
    			}
    		}
    		printf("%d
    " , ans + 1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    IDEA导入springboot项目报错:non-managed pom.xml file found
    Keepalived高可用集群(还没细看)
    Keepalived服务
    *** WARNING
    POJ 2185 Milking Grid (搬运KMP)
    POJ 1961 Period (弱鸡三战KMP)
    POJ 2752 Seek the Name, Seek the Fame (KMP next数组再次应用)
    POJ 2406 Power Strings(KMPnext数组的应用)
    杂模板
    URAL
  • 原文地址:https://www.cnblogs.com/dream1024/p/14960240.html
Copyright © 2011-2022 走看看