zoukankan      html  css  js  c++  java
  • 题解——NYG的动态数点

    题解——NYG的动态数点( 栈的应用 )

    *这道题题解是 nlog^2的,实际上完全没必要,ssw02考场打了个稳定 O( n )把这道题‘水’过了 *


    题面

    Description

    然后私有题面隐藏了

    Input
    一个数N
    N个数ai

    Output
    最大的个数,价值,以及左端点位置

    in.1
    5
    4 6 9 3 6

    out.1
    1 3
    2

    数据范围与约定

    N<= 5e5 , Ai <= 2^32

    思路

    主要思路

    Doggu大佬曾经讲过用栈来处理 1e8 范围的扩展性最小值问题 , 这道题也差不多。

    性质1:合法的值一定是这个区间的最小值

    性质2:合法区间具有连续性

    由上面2个性质,我们很容易想到,用一个栈来维护。

    定义 head 为当前真实影响的栈最优顶值(因为下面 1 情况没有出栈)。

    我们分为3种情况。

    1.新压上来的数可以被 head 所指的数整除,我们不把他出栈,放在栈顶,并且让 head 所指值得贡献增加。

    2.新压上来的数可以整除 head 所指的数,那这个数一定更优,不断弹栈并且累加该值的贡献。

    3.同时不满足上面2种,那么区间连续性中断,head记录为当前该值。

    细节

    注意有的不是贡献++,而是贡献+=被弹出的值的贡献(自己思考咯,ssw02懒得讲喽)

    复杂度

    每个值仅仅会入栈一次,出栈小于等于1次,中途所有细节都仅仅涉及单值查询。复杂度严格 O(n)

    外加ssw02考试写丑了,但时间还是是最快的。

    考试时定义变量重了,就用 son 记录了贡献 , val 记录了原值

    #include<bits/stdc++.h>
    using namespace std ;
    const int MAXN = 500005 ;
    #define ll long long
    inline int read(){
    	int s=0 ; char g=getchar() ; while(g>'9'||g<'0')g=getchar() ; 
    	while(g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ;
    }
    struct Seg{// 稳定的 O(n)做法 
    	ll num , val , l , r , son  ;//作者ssw02:下面的那个可以改成 + t[ u ].l 自己想,实际都一样的
    }t[ MAXN ] ;
    stack<int>q ;
    int N , M , head = 0 , opt[ MAXN ] , op = 0 ; 
    int main(){
    	freopen("point.in","r",stdin);
    	freopen("point.out","w",stdout);
    	N = read() ; if( N == 1 ){cout<<1<<" "<<0<<endl<<1;} 
    	for( int i = 1 ; i <= N ; ++i ){
    		t[ i ].val = read() , t[ i ].num = i , t[ i ].l =  t[ i ].r = 0 ;
    		if( q.empty() ){ q.push(i) ; head = i ; }
    		else{
    			if( t[ i ].val % t[ head ].val == 0 ){
    				t[ head ].r++ ; q.push(i ) ;
    			}
    			else if( t[ head ].val % t[ i ].val == 0 ){//要命 
    				while( q.top() != head ){
    					q.pop() ; t[ i ].l++ ;
    				}
    				t[ i ].l += t[ head ].l+1 ; q.pop() ;
    				while( !q.empty() ){
    					int u = q.top() ; 
    					if( t[ u ].val % t[ i ].val != 0 )break ;
    					q.pop() ; t[ i ].l += t[ u ].l + 1 ; 
    				}
    				q.push(i) ; head = i ;
    			}
    			else if( t[ i ].val % t[ head ].val != 0 ){
    				while( q.top() != head ){
    					int u = q.top() ; 
    					if( t[ u ].val % t[ i ].val != 0 )break ;
    					q.pop() ; t[ i ].l++ ; 
    				}
    				head = i ; q.push( i ) ;
    			}
    		}
    	}
    	for( int i = 1 ; i <= N ; ++i )t[ i ].son = t[ i ].l + t[ i ].r;
    	//for( int i = 1 ; i <= N ; ++i )cout<<t[ i ].son<<" ";
    	ll ans1 = -1  ; 
    	for( int i = 1 ; i <= N ; ++i ){
    		if( t[ i ].son == ans1 )
    			opt[ ++op ] = i - t[ i ].l ;
    		if( t[ i ].son > ans1 ){
    			ans1 = t[ i ].son , op = 1 , opt[ op ] = i - t[ i ].l ;
    		}
    	}
    	cout<<op<<" "<<ans1<<endl ;
    	for( int i = 1 ; i <= op ; ++i  )
    		printf("%d ",opt[ i ] ) ;
    	return 0 ;
    }
    /*
    30
    15 15 3 30 9 30 27 11 5 15 20 10 25 20 30 15 30 15 25 5 10 20 7 7 16 2 7 7 28 7
    */
    

    如有不足,请大佬指出

  • 相关阅读:
    POJ 3080 Blue Jeans
    POJ 1961 Period
    POJ 2185 Milking Grid
    POJ 2752 Seek the Name, Seek the Fame
    斗地主算法的设计与实现--项目介绍&如何定义和构造一张牌
    MyEclipse 免安装版制作
    网络子系统48_ip协议数据帧的发送
    Oracle sql语句执行顺序
    当OOP语言RAII特性发展到functional形式的极致
    FusionCharts属性大全
  • 原文地址:https://www.cnblogs.com/ssw02/p/11528188.html
Copyright © 2011-2022 走看看